Баг или фича fieldset?

    Знаете ли Вы, уважаемые читатели, про такой замечательный и, я бы сказал, прикольный тег fieldset? Думаю, конечно знаете! А часто ли Вы им пользуетесь? Думаю очень редко. Ну ладно, ладно, уговорили — именно вы, уважаемый, достаточно часто его используете, а вот верстальщик Вася из соседней фирмы — точно редко, а может и всего один раз его «пробовал на вкус», когда узнал про него. Ну да ладно, не об этом речь. Если Вы часто его использовали, то возможно натыкались на необычное поведение fieldset, а именно игнорирование width, если вложенный элемент шире и ни какие overflow делу не помогают. Сразу приведу пример. Этот и последующие примеры смотреть в актуальных версиях FF (32) и Хром (35); IE11, как ни странно, показал себя с лучшей стороны и отработал правильно; остальные браузеры не проверял.

    Внимание! В статье все примеры упрощены до максимума — до одного вложенного элемента!

    Ну а теперь давайте вернемся чуть-чуть назад. Бывает часто в жизни, что нам надо скрыть лишние элементы, которые не влезли в отведенный им блок, например сделать карусель. Тут всё ясно:
    1. Назначаем блоку заданную ширину/высоту и overflow hidden или scroll
    2. Внутри, если это случай с каруселькой, задаём ширину/высоту с запасом.
    3. Profit

    Вроде ничего сложного. Пример.

    Но вот случалась ситуация, что нам нужна форма и больной мозг решил использовать для группировки элементов fieldset. Ну ладно не больной мозг, а наоборот — здоровый, ведь это семантично и круто, всё как у взрослых. Пробуем поступить так же, как и обычно.

    Сначала пример с ограничением по высоте. Всё работает как надо по высоте. Можно поставить scroll или просто hidden, если мы хотим отработать прокрутку на JS, результат нас радует.

    Но при этом сразу бросается в глаза, что fieldset занял 100% в ширину и вызывает небольшое недоумение. Думаю каждый сразу же воскликнет: «Так задай ему ширину!» Ну давайте зададим эту ширину! Что же мы видим?.. О вездесущий html тебя побери, что за индусский жук? Fieldset ужался, но до размеров вложенного в него элементов. Это непонятная особенность fieldset, то ли баг, а то ли фича.

    Разумеется есть простое решение — это обернуть внутренности ещё в один блок и уже ему ставить overflow и фиксированную ширину (width).

    Пытался искать решение проблемы, но Google ничего жизнерадостного не говорит, только длинный диалог на bugzilla.mozilla.org, но там я не нашел обсуждения именно этой проблемы. Спецификация по этому поводу тоже ничего внятного не рассказывает. Или я не нашел, в виду слабых познаний английского языка.

    В спецификации видно, что fieldset относится к:
    • flow content, то есть нам это ни о каких особенностях не говорит и не отличает его от, например любимого всеми, div.
    • sectioning root, что означает некие отличительные стили, которые не наследуются потомками, например border у TD и нашего героя fieldset, и у некоторых других свои. Это нам тоже ни чего не даёт и можно проверить на «соседнем» элементе blockquote
    • Listed elements и form-associated elements — это элементы, которые могут/должны иметь родителя form. Тут тоже можно проверить на «соседнем элементе», например button. О результате я думаю вы догадались.
    • Palpable content — это говорит нам о том, что этот элемент должен быть заполнен. Это не обязательное условие, так как этот элемент может быть подготовлен пустым для последующего заполнения дочерними элементами, но рекомендуется не оставлять его пустым. Таких элементов очень много, так что это тоже не то.


    Дальше идёт стандартное описание атрибутов и пару примеров.

    Раз они мне не помогли — будем пробовать разбираться сами.

    Для Хрома оказалось всё просто. У него вшит вендорный min-width: -webkit-min-content, что как бы намекает и о многом говорит, даже не знающему, достаточно просто перевести слова. Это легко было выяснить через встроенные «Инструменты разработчиков». Поэтому решается данная проблема просто, для этого достаточно выставить min-width равный width.

    А вот для FF этот метод не помог. И тут на помощь был призван широко известный в узких кругах метод тыка. Первым же делом на ум приходит выставить display: block. Эта мысль наверное вас посетила не раз с самого начала статьи? Однако ни block, ни inline, ни даже table не подходит. Однако ход мыслей правильный. С помощью перебора всевозможных режимов были найдены несколько, не понятным образом, работающих. Это режимы table-cell или table-column. Так же возможны варианты table-column-group, table-footer-group или table-header-group, но это уже перебор. При чем тут вообще режим ячейки таблицы — даже не спрашивайте. Однако, я считаю это хаком для FF и хотелось бы найти более разумное и правильное решение.

    Решение проблемы с fieldset

    Может найдутся специалисты, которые решали данную задачу другими методами или более подробно знакомы со спецификацией и расскажут что к чему? Или стоит написать в багтреккеры обоих браузеров?

    Ссылка на jsfiddle с примерами для поиграться.

    На этом думаю всё, теперь можно начинать кидаться тапками. Спасибо за внимание.
    • +12
    • 11,8k
    • 9
    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 9
    • 0
      IE10 тоже не сплоховал.
      • 0
        «Решение проблемы» создаёт проблему в Opera 12.17 — теперь <fieldset> растягивается на ширину картинки. Предыдущие примеры работают, как и ожидается: в первом и втором примерах ширина 50px, в третьем и ширина и высота по 50px.

        P.S. Пример с ограничением по высоте у вас ссылается на первый пример, а не на третий.
        • +2
          К сожалению, на данный момент я не знаю решения, которое бы не затрагивало Оперу.

          Могу придложить сделать дополнительно хак для оперы
          @media (min-resolution: .001dpcm) {
              _:-o-prefocus, fieldset { /* стиль только для Opera 12.00+ */
                  display: block;
              };
          }
          

          jsfiddle.net/sa7sg4ks/3/

          Но это уже точно перебор
          image


          PS Спасибо. Исправил.
        • НЛО прилетело и опубликовало эту надпись здесь
          • НЛО прилетело и опубликовало эту надпись здесь
            • НЛО прилетело и опубликовало эту надпись здесь
              • +1
                И всё таки тут дела обстоят немного иначе.

                По вашей ссылке выше на спецификацию fieldset говорится о min-content, который я упоминал в статье, в абзаце про решение для Хрома.

                Это параметр уже появился у Хрома и Фокса у width и, наверное, не только:
                -webkit/moz-min-content
                Попробуйте его выставить для div'а в Фоксе или Хроме.
                developer.mozilla.org/en-US/docs/Web/CSS/width
                min-content
                The intrinsic minimum width.


                Так вот как раз Хром его и использовал в вендорных стилях
                image

                И стоит сообщить, что старые версии Хрома возможно не использовали его, ибо скорее всего не был внедрен min-content и fieldset работал «как надо». То есть Хром на данный момент полностью следует спецификации, в отличие от других.

                Ну IE и Opera судя по всему по старинке.

                А вот у Фаокса чудеса непонятные. Они это как-то по своему решили сделать
                image

                PS Спасибо за ссылку. Если бы я раньше о ней узнал, статья была бы написана уже в дургом ключе.
                • НЛО прилетело и опубликовало эту надпись здесь
              • 0
                Это конечно не значительно и по сути не имеет прямого отношения к багу, но получше просто в webkit сделать min-width: initial, даже можно глобально для fieldset. Тогда не придётся дублировать постоянно с шириной.

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