Почему CSS2.1 определяет значения переполнения, отличные от «visible», для создания нового контекста форматирования блока? - PullRequest
58 голосов
/ 30 марта 2012

Спецификация CSS2.1 требует, чтобы overflow, кроме visible, установило новый "контекст форматирования блока" .Мне кажется странным, что свойство, очевидная цель которого состоит в том, чтобы скрыть переполнение без влияния на макет, на самом деле влияет на макет главным образом.

Кажется, что значения переполнения, отличные от visible, объединяют две совершенно не связанные функции: создан ли BFC и скрыто ли переполнение.Это не похоже на «переполнение: скрытый» без BFC, совершенно бессмысленно, потому что исторически плавающие объекты могут переполнять родительский элемент, скрывать переполнение без изменения макета кажется разумным.

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

Ответы [ 2 ]

66 голосов
/ 08 августа 2012

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

В основном, потому что, если в спецификации это не сказано, то наличие поплавков пересекается с чем-то, что можно прокручивать.потребовалось бы, чтобы браузер перематывал (вокруг всплывающих надписей) содержимое прокручиваемого элемента при каждой прокруткеТехнически это то, что требовалось для CSS 2.0, но оно никогда не было реализовано, и это было бы огромной проблемой для скорости прокрутки.

-David

Скорее всего, это относится кпрокручиваемое содержимое в поле, которое может находиться за пределами родительского объекта поплавка, но пересекается с поплавком.Я не думаю, что это связано с перемоткой содержимого вокруг плавающего элемента в прокручиваемом контейнере, поскольку это уже происходит естественным образом, плюс значение float будет вставляться в контейнер и прокручиваться вместе с остальным содержимым в любом случае .

Наконец, это имеет смысл для меня.На самом деле, я собираюсь привести пример здесь, так что, надеюсь, это имеет смысл для вас и всех, кто, возможно, задается вопросом.Рассмотрим сценарий, включающий два поля с одинаковой фиксированной высотой и overflow: visible (по умолчанию), первый из которых содержит число с плавающей точкой, которое выходит за пределы высоты его родителя:

<div>
    <p>...</p>
</div>
<div>
    <p>...</p>
    <p>...</p>
</div>
/* Presentational properties omitted */
div {
    height: 80px;
}

div:first-child:before {
    float: left;
    height: 100px;
    margin: 10px;
    content: 'Float';
}

Обратите внимание на сходство с одним из примеров, приведенных в раздел 9.5 .Во втором поле здесь просто показано, что содержимое переполнено для целей этого ответа.

Это хорошо, поскольку содержимое никогда не будет прокручиваться, но когда для overflow установлено значение, отличное от visible,это приводит к тому, что содержимое не только обрезается по границам поля, но и становится прокручиваемым.Если второе поле имеет overflow: auto, то это будет выглядеть так, как если бы браузер реализовал оригинальную спецификацию CSS2:

Из-за поплавка при попытке прокрутки содержимогоприведет к тому, что браузеру придется перевернуть его, чтобы он не скрывался поплавком (и что должно произойти с частью, которая прокручивается из верхнего края?).Вероятно, это выглядело бы примерно так при прокрутке вниз:

Проблема в том, что браузер должен перематывать содержимое каждый раз, когда перерисовывает его во время прокрутки.Для браузеров, которые поддерживают плавную прокрутку на основе пикселей, то есть все они, я понимаю, почему это приведет к падению производительности!(И опыт пользователя тоже.)

Но для этого пользователь может прокручивать контент, верно?Это имело бы смысл для overflow: auto и overflow: scroll, но как насчет overflow: hidden?

Что ж, распространенное заблуждение состоит в том, что контейнер с overflow: hidden просто скрывает содержимое путем отсечения и не может быть прокручен. Это не совсем верно :

Хотя пользовательский интерфейс прокрутки не предусмотрен, контент все еще прокручивается программно, и некоторые страницы выполняют такую ​​прокрутку (например, установив * 1057)* на соответствующем элементе).

-Борис

Действительно, это то, что выглядело бы, если бы для второго поля было установлено значение overflow: hidden, а затем прокрутка до днасо следующим JavaScript:

var div = document.getElementsByTagName('div')[1];
div.scrollTop = div.scrollHeight;

Опять же, обратите внимание, что контент должен быть перемотан, чтобы не быть скрытым поплавком.

Даже еслиэто не было бы столь же болезненно для производительности, как если бы был доступен прокручиваемый пользовательский интерфейс, я думаю, что они создали боксы со значением any overflow, отличным от visible, генерирующим новый BFC главным образом радисогласованность.


Итак, это изменение было внесено в CSS2.1, задокументировано здесь .Теперь, если вы примените значение overflow, отличное от visible, только ко второму блоку, браузер отодвинет весь блок , чтобы освободить место для поплавка, потому что блок теперь создает новыйблок форматирования контекста, который заключает в себе его содержимое, вместо обтекания поплавка.Это конкретное поведение указано в следующем абзаце :

Граничный блок таблицы, замененный элемент уровня блока или элемент в нормальном потоке, который устанавливает новыйконтекст форматирования блока (например, элемент с «переполнением», отличным от «видимого») не должен перекрывать поле полей любых плавающих элементов в том же контексте форматирования блока, что и сам элемент.Если необходимо, реализации должны очистить указанный элемент, поместив его ниже любых предыдущих поплавков, но могут разместить его рядом с такими поплавками, если есть достаточно места.Они могут даже сделать границу указанного элемента более узкой, чем определено в разделе 10.3.3 . CSS2 не определяет, когда UA может поместить указанный элемент рядом с плавающей точкой или насколько указанный элемент может стать уже.

Вот как это выглядит с overflow: auto, например:

Обратите внимание, что зазора нет;если бы во втором боксе было clear: left или clear: both, его бы оттолкнули вниз , не в сторону, независимо от того, установил ли он свой собственный BFC.

Если вы примените overflow: autoвместо этого в первый блок поплавок вставляется в контейнер с остальным содержимым из-за его фиксированной высоты, которая установлена ​​в 80px в приведенном выше примере кода:

Если вы вернете первое поле в height: auto (значение по умолчанию), либо переопределив, либо удалив объявление height: 80px сверху, тогда растянет до высоты поплавка:

Это также новинка в CSS2.1 , в которой элемент с height: auto генерирует новый контекст форматирования блока (т.е.корень контекста контекста форматирования блока ) будет растягиваться по вертикали до высоты его плавающих элементов, и этого будет недостаточно, чтобы вместить содержимое в потоке, в отличие от обычного блока.Изменения задокументированы здесь и здесь .Изменения, приводящие к побочному эффекту сжатия коробки, чтобы она не пересекала поплавок, задокументированы здесь .

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

4 голосов
/ 30 марта 2012

Я знаю, что это будет спекулятивный ответ, однако после прочтения спецификаций несколько раз вот мой взгляд на это:

О чем говорит раздел 9.4.1, это любой элемент блока, который не содержит полностьюили не заполняет пространство сдерживания.Например, когда вы перемещаете элемент, он больше не заполняет 100% родительского элемента, как это делают элементы в потоке.Встроенные блоки, ячейки таблицы и заголовки таблиц также являются элементами, на которые можно влиять по высоте и ширине, но которые по сути не являются 100% родительскими (да, таблица> tr> td - это та, которая будет заполнять 100% родительской, но она предназначеначтобы разрешить несколько тд, чтобы тд не учитывался, так как он автоматически сжимается для размещения дополнительных тд), это также относится к любому переполнению, кроме видимого, поскольку оно нарушает удержание элемента блока.

Так что еслия правильно читаю это, как это работает, раздел 9.4.1 ссылается на элементы блока, которые нарушают правила содержания по умолчанию для элементов блока, как указано в разделе 9.2.1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...