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

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

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

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

 BoltClock♦30 мар. 2012 г., 15:06
@Timwi: в идеале такие вопросыделать иметь окончательные ответыне должен быть закрытым, но это действительно зависит от сообщества, чтобы решить. Видетьэтот мета пост, На самом деле я не решался опубликовать это на SO самостоятельно по упомянутой причине, а также по поводу всей спекуляции, и вместо этого занес это в список рассылки. Но я понял, какого черта, давайте посмотрим, как это происходит. Если есть слишком много спекулятивных ответов, мы можем позволить сообществу обработать это, или я могу ответить на флаги.
 Roman Starkov30 мар. 2012 г., 15:09
@BoltClock У меня тоже были оговорки, поэтому я попытался сформулировать это осторожно, чтобы не допустить спекуляций. Авторитетный ответ был бы лучшим, конечно. Отличный пример на Мете, кстати.
 BoltClock♦28 мая 2012 г., 19:07
Похоже, мы полностью забыли об этом вопросе. К сожалению. Вы хотите, чтобы я опубликовал ответ, цитируя ответы в ветке списка рассылки?
 Timwi30 мар. 2012 г., 15:03
Это необычно; другие вопросы, которые аналогичным образом предполагают умозрительные ответы и / или на которые отвечают только те немногие люди, которые участвуют в принятии решения, обычно закрываются. Этот сайт действительно не соответствует закрытию вопроса.
 BoltClock♦02 апр. 2012 г., 05:25
Я отправил ваш вопрос в список рассылки:lists.w3.org/Archives/Public/www-style/2012Apr/0023.html

Ответы на вопрос(2)

Решение Вопроса

Вот, В итоге,это связано с прокруткой контента по большей части:

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

-Давид

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

Наконец это имеет смысл для меня. На самом деле, я собираюсь привести пример здесь, так что, надеюсь, это имеет смысл для вас и всех, кто, возможно, задается вопросом. Рассмотрим сценарий, включающий две коробки с одинаковой фиксированной высотой и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 просто скрывает содержимое путем отсечения и не может быть прокручен.Это не совсем верно:

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

-Boris

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

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

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

Несмотря на то, что это не было бы так болезненно для производительности, как если бы был доступен прокручиваемый пользовательский интерфейс, я думаю, что они делали коробки сЛюбые 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 который генерирует новый контекст форматирования блока (т.е.корень контекста форматирования блока) будет растягиваться вертикально до высоты поплавков, и этого будет недостаточно, чтобы вместить содержимое в потоке, в отличие от обычного блока. Изменения документированыВот а такжеВот, Изменения, приводящие к побочному эффекту сжатия коробки, чтобы она не пересекала поплавок, задокументированыВот.

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

 HRJ29 сент. 2016 г., 13:33
неoverflow:visible прокручивать тоже?
 BoltClock♦29 сент. 2016 г., 13:55
@HRJ: Нет, это не так.

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

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

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

 BoltClock♦07 авг. 2012 г., 23:43
Ваше резюме оказывается частично правильным. Хотя вместо того, чтобы нарушать правила, они просто устанавливают для них разные правила. Смотрите последнюю часть моего ответа для объяснения.

Ваш ответ на вопрос