CSS-live.ru

Чиним решение SelenIT-а по очистке потока, или Новый lol над Opera 12.00

Приветствую, дорогие друзья!

Сегодня пишу эту статью для Вас (как всегда среди ночи), чтобы рассказать занимательную историю о маленьком браузере. О его плохом воспитании и — как следствие — плохом поведении. Действия которого, нарочно или нет, приносят массу проблем разработчикам. По совету Макса (a.k.a Psywalker) разделю сие повествование на три части:

  • Проблема
  • Решение
  • Пикантные подробности

Итак, поехали!

Часть первая: Проблема

Совсем недавно Ильей Стрельцыным (a.k.a @SelenIT2) было предложено оригинальное решение по очистке потока (не по приниципу известного «clearfix», а путем создания нового блочного контекста форматирования, сродни overflow:hidden, но без его главного недостатка). Оно было принято на вооружение. Но вскоре выяснилось, что, тогда еще Opera 11.60Opera 12.00 этот момент так же не исправлен), не совсем корректно справлялась с поставленной для нее задачей, а именно — появлялись непонятные отступы под элементом, к которому был применен этот хак первой версии.

Рис 1. Сравнение отображения в Google Chrome и Opera

Первая версия решения Ильи Стрельцына (a.k.a @SelenIT2):

/* метод Ильи Стрельцына */
.new_context {
    -height: 1%;
    *zoom: 1;

    /* display: table */
    display: table;
}
/* Очень важное дополнение! */
.new_context:after {
    content: '. .';
    display: block;
    word-spacing: 99in;
    height: 0;
    overflow: hidden;
}

По моему предложению, css был немного дополнен, добавлением к псевдо-элементу свойств font-size и line-height со значением 0.05em, подобранных опытным путем. В итоге был получен рабочий css, который работал одинаково во всех браузерах.

/* метод Ильи Стрельцына */
.new_context {
    -height: 1%;
    *zoom: 1;

    /* display: table */
    display: table;
}
/* Очень важное дополнение! */
.new_context:after {
    content: '. .';
    display: block;
    word-spacing: 99in;
    height: 0;
    overflow: hidden;

    /* Лекарство бага с отступом в Opera */
    font-size: 0.05em;
    line-height: 0.05em;
}

Все были счастливы до недавнего времени, а именно, до того момента, как Александр Т. (a.k.a Softlink) не отписался в общем чате о проблеме с данным решением в Opera 12.00.

Проблема состоит в том, что блок, к которому был применен этот метод очистки потока, не занимал всю доступную ширину окна или род. блока, а схлопывался по ширине наполняющего его контента.

Рис 2. Вид из Opera 12.00

Часть вторая: Решение

События развивались все в том же чате, Максим Усачев (a.k.a Psywalker), Александр Т. (a.k.a Softlink) и Я, устроили такой себе мозговой штурм, направленный на решение проблемы.

В ходе исследований выяснилось, как говорилось выше, что если содержимое блока короткое по ширине, то в Opera 12.00 блок с очисткой потока всё-таки схлопывается по контенту. Также было обнаружено, что при условии наполнения блока параграфом с достаточным количеством текста конструкция начинала себя вести как положено.

В результате родилось решение, которое смогло победить проблему и вернуть состояние вещей в нужное русло.

Новая версия способа очистки потока Ильи Стрельцына (a.k.a @SelenIT2) с нашим дополнением:

/* метод Ильи Стрельцына */
.new_context {
    -height: 1%;
    *zoom: 1;

    /* display: table */
    display: table;
}
/* Очень важное дополнение! */
.new_context:after {
    content: '. . . . . . . . . . .'; /* Решение проблемы в Opera 12.00 */
    display: block;
    word-spacing: 99in;
    height: 0;
    overflow: hidden;

    /* Лекарство бага с отступом в Opera */
    font-size: 0.05em;
    line-height: 0.05em;
}

Это финальный рабочий вариант, который можно смело применять в своих проектах.

Рис 3. Вид из Opera 12.00 с применением доработанного решения

Часть третья: Пикантные подробности

Вот проблема решена, всем спасибо… Но погодите расходиться! Тут начинается та часть, которая вызвала у нас откровенный смех над ситуацией.

Собственно, как мы пришли к варианту content: '. . . . . . . . . . .'; ? Скажу честно: нам помогли инопланетяне ;) Ладно-ладно…

После того как я сказал, что блок схлопывается по содержимому, Максима осенило. Исходя из теории, по которой Илья Стрельцын пришел к такому варианту очистки потока, то многое решает псевдоэлемент ::after, а именно content: '. .'; и word-spacing: 99in;. Эти свойства создают в блоке псевдоэлемент очень большой ширины — 99 дюймов или 9504 px, который собой распирает блок до максимально доступной ширины родителя.

Казалось бы, чему тут ломаться? И вправду, ломаться здесь нечему, но Opera смогла сломать это. Максим сначала предложил вставить случайную строку с пробелами в content псевдоэлемента, следом выдав вариант с очень длинной строкой точек с пробелами. Тут мы начали понимать, что слишком длинная строка ни к чему. После ряда шаманских манипуляций у меня получился собственно конечный вариант content c 11-ю точками, между которыми были пробелы, в Опере это дало 3321px в ширину, чего вполне достаточно для любой ширины экранов, доступных на данный момент.

Следом Александр Т. обратил внимание на то, что точка-пробел-точка дают примерно 300px ширины в Опере, и что это наверняка можно как-то использовать. Я решил сравнить поведение псевдоэлемента в Опере и Хроме, особое мое внимание, на фоне закономерности обнаруженной Александром, привлекло свойство word-spacing. word-spacing — это свойство, которое способно задавать интервал между словами и может принять на вход normal или значение в CSS-единицах длины (px|in|pt и др.). Все нормальные браузеры способны принять значение в px в соответствии с типом данных smallint, то бишь 65535px, но не Опера 12.00. У нее оказалось очень странное ограничение, максимум которого равен всего-навсего 328px! Причем можно ставить хоть 100500px, все равно это будет 328px. 328? Что это за число? Налицо применение «Магических чисел», что не может не веселить. Следствием такого весьма странного бага (или индуских промыслов) стал крах предыдущего решения очистки потока. Но решение найдено, и это хорошо. Советуем внести изменения в Ваши проекты, пока вас не «спалили» ;)

По моему мнению, это достаточно глупый глюк, и он не первый, а судя по тенденции развития это еще не последняя проблема, которая возникнет в будущем. Ребятам из Opera Software явно нужно «подправить что-то в консерватории», а то такие вот «ложки дёгтя» с элементарными вещами в их продукте ну никак не способствуют его успеху в конкурентной борьбе…

P.S. Выражаю особую благодарность Илье Стрельцыну (a.k.a @SelenIT2) за его детище. Максиму Усачеву (a.k.a Psywalker) и Александру Т. (a.k.a Softlink) за совместный поиск варианта адаптации решения под новые условия. Дорогим читателям, которые выдержали меня столько времени). Ну и, конечно, Opera Software, обеспечившая разминку мозга на ночь глядя.

На этом все. С вами в эфире был Алекс (a.k.a alexriz). Никогда не сдавайтесь, добивайтесь целей, и да пребудет с вами сила!
Всем удачи, всем пока!

P.S. Это тоже может быть интересно:

30 комментариев

  1. Поиздевались на славу, вы большой молодец. Теперь не забудьте написать багрепорт (в багтрекер или прямо мне), а то многие забывают. Я вот не забуду:
    не к чему (ни к чему)
    // Решение проблемы — это невалидный CSS-комментарий, который поломает код тому, кто это скопирует.

    1. Вадим, спасибо за отклик и замечания! Пользуясь случаем (чтоб два раза не вставать, как говорится), хочу еще спросить на близкую тему (насчет поведения letter-spacing в Опере): как объясняются два "скачка" при уменьшении letter-spacing-а между инлайн-блоками (при -0.28 и -0.45 em) в этом примере? Можно ли считать их багом (особенно второй) и есть ли смысл ждать фикса?

      1. Я посмотрю что не так в примере, спасибо. Может быть из этого получится баг.
        Но вам серьёзный совет: строить сетку на основе дробей -0.28em или прикидывая какой там ширины пробел, т.е. вещей недокументированных, принципиально по-разному реализованных, это чистой воды суицид, об этом уже много раз уже писали.

        1. Я сам об этом писал :) Но тогда я честно думал, что в Опере letter-spacing вообще не действует на пробелы. Потом начал копать глубже, и всё оказалось еще интереснее!

    2. Никто не издевался, просто с юмором отнеслись, как и сама статейка :) На счёт багрепорта отпишем именно тебе. Недавно тебе писал кстати, ты не отреагировал никак(

      И спасибо за замечания, не доглядели, всё исправили)

    3. На самом деле я не издевался ни разу, а всего лишь обратил внимание на эпичность возникшей проблемы. Просто стоит принять на вооружение, что есть такая проблема с Вашим продуктом, и не обижаться на ровном месте.

       

      Я вот не забуду:
      не к чему (ни к чему)
      // Решение проблемы — это невалидный CSS-комментарий, который поломает код тому, кто это скопирует.
      Да не вопрос принято, будет исправленно, спасибо за Ваш комментарий!
      1. > Новый lol над Opera 12.00
        > индусский промысел
        > подправить в консерватории
        По-моему, «гы, лол» это чистой воды издевательство, что ни говорите. Обижаться я разучился, просто призываю вас вести себя взрослее.

        1. Быть врослым и смотреть на мир с грустным|сдавшемся|разачарованным|унылым (нужное подчеркнуть) взглядом — это несколько разные вещи. Разводить меланхолическое настроение не вижу смысла, это никому не интересно. Всем свойственно ошибаться, это нормально. Только одни спотыкаются, сдаются и падают вниз, а другие делают выводы, исправляются, становятся сильней и не боясь поднять взгляд идут покорять новые вершины! Очень надеюсь, что Вы относитесь ко второй группе ;)

          Проводить мотивирующие лекции я могу долго, но здесь этому не место)

          1. Просто вы за своими «гы-лол» теряете элементарную вежливость и вместо того, чтобы предположить по какой причине было введено ограничение (или спросить у людей, которые это знают), начинаете иронизировать по поводу индусов-идиотов — хотя по факту это норвежцы-шведы-поляки и кто угодно, умнейшие ребята. И мне, читая ваш текст, за них очень обидно.
            У каждого свойства или метрики в каждом браузере есть определённые ограничения, которые позволяют быстро обрабатывать страницы. А текст до сих пор один из самых сложных объектов для отрисовки, просто из-за того, что из-за многочисленных влияний он часто перерисовывается. Что такое word-spacing? Это свойство, регулирующее расстояние между словами в тексте. Его значение было установлено в «uses 15 bits to store word-spacing as a fixed-point (2 decimals) integer» (цитирую нашего инженера), т.е. в разумных рамках. В итоге, максимальное значение это 327.67.
            А в Firefox и Safari максимальное значение 18199px (а не smallint, как вы утверждаете). Причём после его достижения второе слово не просто продолжает отставать от второго на 18199 пикселов, а вообще исчезает.
            328px или 18199px — это эпический «гы-лол»? Не знаю. Для хака, которым является использование свойства word-spacing в этом случае, практически равносильно. Имеет ли смысл в реальной жизни, для текста? Нет.
            Такие шутки.

            1. Согласен и 328 и 18199 эпично, но вот только с 18199 было все нормально, а 328 доставило проблемы, вот и разница. Я не вижу принципиальной разницы обрабатывать 18kpx и 328px. Не спорю текст это очень сложный объект для обработки. Да нужно оптимизировать, если можно экономить, то нужно экономить, но в разумных пределах. А так получается какая-то фанатическая погоня, которая в итоге приводит только к проблемам. Если бы от этого еще страница рисовалась быстрей, а так, то оно по факту выходит совсем не быстро.

              Отсутствие дробных процентов, тоже экономия? Об этой проблеме говорят с давних времен, 100500 раз было написано в багтрекер, все ясно говорили, что такая экономия ни кому даром не нужна. С единицами мер, вообще смотрю глобальная проблема. С псевдо-элементами тоже хватает косяков. С рисовкой svg проблемы, который откровенно отпадает, но это не так критично. Какие-то необъяснимые перескоки скролла страницы. Список можно продолжать.

              Вот вроде бы каждое по отдельности — мелочь, а в скопе приводит к существенным проблемам. Во всех браузерах есть косяки, но только эти косяки в большенстве своем не приносят таких хлопот. 

  2. Вчера тоже обновила Оперу. Верстка — последнее, на что я обратила внимание. А вот то, что дебаггер стал ругаться на некоторые строки библиотеки jquery, стало неожиданностью. И всякие глюки в ранее рабочих скриптах появились, не пропадают, пока не закроешь/откроешь вкладку/браузер. Предполагаю, что , как минимум, надо будет обновить версию jquery на корпоративном сайте до самой последней.
    (Метод с псевдоэлементом, содержащим много текста, я уже год использую. Методом проб и ошибок поняла, что letter-spacing = 200px меня вполне устраивает. Но эти ограничения были связаны с тем, что контейнер растягивался по самому большому слову. Т.е. задача была чуток другая. Возможно, кому-то это пригодится: http://matiasrust.ru/css/fascinating-css/three-columns-for-seo. Там благодаря псевдоэлементам решалась задача трехколоночной резиновой верстки. Спасибо за подсказку Антону П. — нашему дизайнеру.)

    1. Ух ты. В ваше решение я не подглядывал, честное слово. Поистине "great minds think alike" :). Хотя идея, действительно, не так уж глубоко и запрятана была…

    2. Matias Rust, задачу с трехколоночной резиновой версткой можно решить добавлением еще одной обертки вокруг контента (http://blog.html.it/layoutgala/LayoutGala13.html). Работать будет в IE7 и ниже, где не поддерживается генерируемое содержимое.
      А вот еще классный пример использования распорки из генерируемого содержимого http://css-tricks.com/minimum-paragraph-widths/

    3. В общем, для восстановления справедливости, пальму первенства идеи, видимо, надо отдать Николь Салливэн (aka Stubbornella). Хотя туда я тоже не подглядывал, и кода в нашем решении всё-таки чуточку поменьше).

      Впрочем, с приходом флексбоксов, а теперь и гридов, мучения с «очисткой потока» после флоатов скоро всё равно останутся в прошлом.

  3. Да, когда требовалась поддержка ИЕ6-7, приходилось добавлять такой оберточный див. Около пяти макетов так сделала.
    Но всегда хочется верстать лучше, чище, светлее. Поэтому я каждый день читаю css-live.ru.
    И да, распорки из генерируемого содержимого по последней ссылке довольно хороши.

  4. Объясните пожалуйста: зачем это все? 
    Чем ваше решение лучше, чем стандартный современный clearfix, который работает везде и имеет более понятную логику работу?  
     
    .clear:before, .clear:after{
    content: "";
    display: table;
    }
    .clear:after{
    clear: both;
    }
    .clear{
    zoom: 1;
    }
     
     

        1. Посмотрите демку из той статьи. «Micro clearfix» Галлахера (кстати, упомянутый там в комментах) будет в ней вести себя полностью эквивалентно классическому клирфиксу. Что явно не соответствует подразумеваемой задаче :)
          У clearfix-ов (любых!) один принцип действия, а у overflow:hidden и нового метода — другой. Ну и у каждого способа свои ограничения и разные области применения, само собой. Новый способ — для случаев, когда ограничения клирфиксов и overflow неприемлемы.

  5. Хочу выразить огромную благодарность всем авторам — спасибо вам, ребята! Способ успешно применяю))

    1. согласен, авторам спасибо, но вы лучше всем своим клиентам, друзьям, знакомым и родственникам удаляйте программу опера, и устанавливайте браузер, они только спасибо скажут — да и вы удовольствие получите за принесенное добро людям!!!

      вот ссылка для использования https://www.google.com/intl/ru/chrome/browser/?hl=ru и будет вам счастье!!!

        1. я когда-то тоже думал что в DAEWOO LANOS самое лучшее управление, пока не сел за руль HONDA ACCORD, в которой с первого взгляда показалось все хуже чем LANOSе.
          Привычка-дело страшное, вот и вы привыкли к интерфейсу оперы, и вам страшно использовать что либо другое, потому что оно вам не знакомо.
          но стоит только попробовать, и вы уже назад не вернетесь к худшему. Я так тоже рассуждал когда переходил с мозилы на хром, ведь в хроме я не знал где что находится — просто понравилось быстродействие.
          А для вас главным условием является интерфейс? — для меня как и для многи,  быстродействие!
           

        2. Это ты дебил, причём тупой, Опера дерьмо, вот когда она будет нормлаьно работать тогда и скажешь про интрефейс и всё остальной, кстати по поводу интерфейса она у хрома сосёт.

        3. Господа, брэк! С фанатскими разборками, чей любимый браузер круче — плз, не сюда, а на форум.

          Все браузеры — дерьмо. Ни один из них не держит полностью ни одного стандарта, все глючат в самых неожиданных и непредсказуемых местах и невпопад ломаются на самом, казалось бы, безобидном коде. Сами стандарты, кстати — тоже лажа, запутанная и нелогичная. И вообще жизнь несправедлива. Но если бы было иначе — разве была бы работа верстальщика/вебмастера так интересна? ;)

  6. Вообще странно что кто-то еще использует оперу — 21век уже. А еще более странно что кто под нее делает фиксы!
    Ребята, не используйте программы по типу oPERA и IE, скачайте браузер Google Chrome и пользуйтесь, и нервы спокойнее пока страница грузиться, да и страницы в Google Chrome выглядят куда более привлекательней.
    А разработчикам оперы совет — бросьте это гиблое дело, оно вам не по зубам, ну или спросите у кого нибудь совет как сделать нормально без багов и глюков.
    Мне это напоминает: "Программист не тот кто пишет программы, а тот чьи программы работают" так вот, опера — г…но!!!
     

Добавить комментарий для alexriz Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.