Як працює контекст форматування блоків CSS?


80

Як працює контекст форматування блоків CSS ?

Специфікація CSS2.1 говорить, що в контексті форматування блоків поля розміщуються вертикально, починаючи зверху. Це трапляється, навіть якщо на шляху є плаваючі елементи, крім випадків, коли блок-блок встановив новий контекст форматування блоку. Як ми знаємо, коли браузери відображають блокові блоки у контексті форматування блоків, плаваючий елемент опускається, чому встановлення нового контексту форматування блоку працює?

Як розміщуються коробки (блок-коробки та вбудовані коробки) у звичайному потоці?

Я десь читав, що елементи блоку генерують блок-бокси, але плаваючі елементи ігноруються, коли користувальницький агент малює поле і враховує їх, коли вони заповнюють вміст. Хоча плаваючі елементи будуть перекривати кордони інших елементів у полях, рішенням є встановлення нового контексту форматування блоків для елементів, що перекриваються overflow:hidden.

"Новий контекст форматування блоків все ще є форматуванням блоків", тому, малюючи поле, він також буде поводитися з плаваючим елементом, як ніби не виходить. Це правильно чи я неправильно зрозумів "контекст форматування нового блоку?"

Оновлення: більше запитань

Сказавши: "Це така поведінка корисна для макетів у стовпчастому стилі. Однак основне використання цього полягає у зупинці плаваючих знаків, скажімо в div" main content ", фактично очищаючи плаваючі бічні стовпці, тобто плаваючі, які з'являються раніше у вихідному коді".

Я не розумію значення, я наведу приклад, можливо, ви мене зрозумієте.

Я думав, що плаваюча коробка повинна плавати у верхній частині контактуючого блоку - div з класом content. Крім того, якщо плаваюче вікно з’являється раніше в розмітці, тоді воно відображатиме те, що, на мою думку, має бути.

Як ми можемо це пояснити? Чи можемо ми використати "контекст форматування блоків та контекст вбудованого форматування", щоб пояснити це?


Не могли б ви додати зображення, щоб задокументувати те, що ви не розумієте?
mrk

Я знаю, що вас явно не запитують про плаваючі операції, але я думаю, що ця стаття дійсно добре пояснює, як працює потік веб-сторінки, і це може допомогти вам зрозуміти це.
Ніклас Вульф,

Відповіді:


126

Контексти форматування блоків

Плаваючі елементи, абсолютно розташовані елементи, контейнери блоків (наприклад, вбудовані блоки, комірки таблиці та підписи таблиць), які не є блоками, та блоки з "переповненням", відмінним від "видимого" (за винятком випадків, коли це значення розповсюджене до області перегляду) встановлюють нові контексти форматування блоків для їх вмісту.

З моїм напівжирним шрифтом, це важливий біт встановлення

Це означає, що елемент, який ви використовуєте overflow(що-небудь, крім видимого) або floator inline-block..etc on, відповідає за макет своїх дочірніх елементів. Потім дочірні елементи "містяться", незалежно від того, чи це плаваючі або згортаються поля, вони повинні повністю містити їх обмежуючий батько.

У контексті форматування блоків лівий зовнішній край кожного вікна торкається лівого краю вміщуваного блоку (для форматування справа наліво торкаються правої кромки)

Що означає наведений вище рядок:

Оскільки коробка може бути лише прямокутної та не неправильної форми, це означає, що новий контекст форматування блоку між двома поплавцями (або навіть поруч з одним) не буде обертатися навколо сусідніх поплавців. Внутрішні, дочірні скриньки можуть поширюватися лише настільки, що торкаються батьків ліворуч (або праворуч у RTL). Саме така поведінка корисна для макетів у колончастому стилі. Однак основне його використання полягає у зупинці плаваючих значень, скажімо, у div "main content", фактично очищаючи плаваючі бічні стовпці, тобто плаваючі, які з'являються раніше у вихідному коді.


Очищення поплавця

За звичайних обставин флоати повинні очищати всі попередні плаваючі елементи, які раніше розміщувались у цілому вихідному коді, а не лише у вашій відображуваній "колонці".

Ця властивість вказує, які сторони вікна (елементів) елемента можуть не знаходитись поруч із попереднім плаваючим вікном. Властивість 'clear' не враховує плаваючі функції всередині самого елемента або в інших контекстах форматування блоків

Отже, скажімо, у вас є макет із трьома стовпцями, де лівий та правий стовпці плаваються відповідно ліворуч та праворуч, бокові стовпці тепер знаходяться в нових контекстах форматування блоків, оскільки вони плаваючі (пам’ятайте, плаваюча є також однією з властивостей, яка встановлює новий BFC ), так що ви можете з радістю розміщувати елементи списку всередині них, і вони очищають лише поплавці, які вже знаходяться всередині бічних стовпців, про які вони вже не дбають про поплавці раніше у вихідному коді


Зробити основним вмістом новий контекст форматування блоків чи ні?

Тепер, коли середній стовпець, ви можете просто розмістити його з обох сторін, щоб він акуратно сидів між двома стовпчиками, що плавають, і взяв решту ширини - звичайний спосіб отримати бажану ширину, якщо центральна колонка є "текучою" - що буде будьте добре, доки вам не потрібно буде використовувати плаваючі символи / кліренси всередині div вмісту (загальне явище для тих, хто використовує хакери чи шаблони "clearfix", включаючи їх)

Візьміть цей дуже простий код:

Він видає наступне:

введіть тут опис зображення

Загалом це нормально, особливо якщо у вас немає кольорів тла або внутрішніх (в основному вмісті) плаваючих - зауважте, що плаваючі чудові (ще не очищені), вони роблять, мабуть, те, що ви, крім них, але вони, H3топ margin та pнижнє поле в дійсності насправді не містяться у div вмісту (світло-сірий фон).

Отже, до того самого простого маргінального сценарію вищевказаного коду додайте:

.clear-r {clear: right;}

на CSS і змініть другий плаваючий блок HTML на:

<div class="floated clear-r"> this a floated cleared box</div>

Цього разу ви отримуєте таке:

введіть тут опис зображення

Другий поплавок очищає праву сторону, але очищає всю висоту правої колони. Правий стовпець розміщений раніше у вихідному коді, тому це очищається, як сказано! Можливо, це не бажаний ефект, але також зауважте, що поля h3та pполя все ще згорнуті (не містяться).


Зробіть так, щоб він створив контекст форматування блоків заради дітей!

і нарешті змусьте головну колонку вмісту взяти на себе відповідальність - станьте контекстом форматування блоків - за її вміст: видаліть margin: 0 200px;із основного вмісту CSS та ADD, overflow: hidden; і ви отримаєте це:

введіть тут опис зображення

Це, мабуть, набагато більше схоже на те, що ви очікували б зробити, зауважте, тепер поплавці містяться, вони очищаються належним чином, ігноруючи правий бічний стовпець, а також поля h3і pполя містяться замість згортання.

Завдяки широкому використанню скидів сьогодні поля є менш помітними (і IE все ще не зовсім їх розуміє), однак те, що щойно сталося з "основним вмістом" центру, це те, що він став контекстом форматування блоків і тепер відповідає за його власні дочірні (нащадкові) елементи. Це насправді дуже схоже на уявлення Microsoft про раннє існування hasLayout, воно використовує ті самі властивості display: inline-block, floatі overflowбудь-що інше, ніж видиме, і, звичайно, комірки таблиці завжди мають макет .. однак без помилок;)

Сподіваюся, це трохи допоможе, будь-які питання сміливо задавайте!


Оновлення: додаткова інформація, про яку йдеться:

Коли ви говорите "але плаваючі елементи ігноруються, коли користувальницький агент малює вікно та враховує їх, коли вони заповнюють вміст."

Так, поплавці зазвичай накладають свої контейнерні ящики, чи це ви маєте на увазі про батьківські межі? Коли блок-елемент намальований і він містить плаваючий, сам батьківський блок малюється у вигляді прямокутника під поплавцем, і це "вбудовані анонімні поля" або просто "рядкові рядки" інших дочірніх елементів, які скорочуються, щоб звільнити місце для поплавок

Візьміть цей код:

Що виробляє це:

як працюють поплавки

Ви бачите, що батьківський елемент насправді не містить float, оскільки він не обертає його повністю .. float просто плаває поверх вмісту - якби ви продовжували додавати вміст до div, він з часом обернувся б під поплавком, оскільки не було б потреби в (анонімних) "рядках" pелемента більше скорочувати себе.

Я забарвив елемент абзацу, щоб ви могли бачити, що він теж насправді потрапляє під поплавок, темно-сірий фон - там, де починається абзац, білий текст - там, де починається "поле анонімного рядка" - це лише вони, які "звільняють місце" "для float, якщо ви не вкажете інше (тобто не зміните контекст)

Знову ж таки, посилаючись на наведене вище зображення, якщо ви хочете зробити поле лівою стороною pелемента, так, це зупинить обтікання тексту під нижньою частиною поплавця, оскільки "рядки рядків" (білий текст) торкнуться лише лівого краю їх контейнер, і ви виведете кольоровий фон pправоруч, за межами поплавця, але ви не змінили поведінку pконтексту форматування. Як центральна колонка на першому зображенні вище;)


clairesuzy, велике спасибі! Це дійсно мені дуже допомагає. Але у мене все ще є кілька питань. Я додав його до оригінальних питань. Сподіваюся, ви можете мені допомогти.
Айлін Тао

1
@eileen відбувається дві речі - я думаю, що ваше додаткове запитання пояснюється першим прикладом .. фіолетові плаваючі вікна з'являються після вмісту, тому що саме там вони знаходяться у джерелі, плаваючий не спливає вгору, перейдіть вище попереднього вмісту (як у верхньому полі не може бути вищим, ніж має бути) - лівий та правий стовпці також є плаваючими полями, які перебувають раніше у джерелі, і без того, щоб середній стовпець став новим BFC, якщо ви спробуєте очистити фіолетові поплавки, вони також очистить попередні плаваючі стовпці на стороні джерела .. це допомагає?
clairesuzy

1
@eileen, що посилання описує елементи рівня блоку та вбудований елемент рівня, лише основи не стільки в контексті форматування. елементи блоку завжди прийматимуть 100% ширини і сидітимуть один на одному (за замовчуванням) - вбудовані елементи сидять поруч, як посилання, прольоти тощо. навіть не беруть ширину чи висоту, тому у них немає можливості. Плаваючий елемент автоматично стає елементом рівня блоку, тому, якщо ви плаваєте за вбудованим рівнем, <span>він стає як рівень блоку <div>.
clairesuzy

1
продовження. Причина, по якій pфон потрапляє під поплавок, полягає в тому, що плаваючі елементи видаляються з потоку, як і в сусідніх елементах, насправді не знають, що вони там, і тому, що вони належать до того самого контексту форматування, як pвиглядає це батьківський контейнер для своїх розмірів .. (саме тому ви не можете поставити річ із шириною 100% поруч із поплавцем - тому що 100% це 100% контейнера. Тільки анонімні вікна нарешті з’ясовують, що там є поплавок; )
clairesuzy

1
@clairesuzy - Зображення, яке ви опублікували, вийшло, чи не могли б ви зробити його репост?
bfavaretto
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.