8 ответов:
вы могли бы поместить два плавающих дива в другое тот, который имеет "переполнение: скрытый" набор:
<div style='overflow:hidden'> <div style="float: left;">Left</div> <div style="float: right;">Right</div> </div> <div style="clear: both; margin-top: 200px;">Main Data</div>edit - чтобы добавить немного к этому 5-летнему ответу: я думаю, что причиной запутанного поведения является несколько сложный процесс маржа развал. Хороший трюк с оригинальным HTML из OP-это добавить правило CSS следующим образом:
div { border: 1px solid transparent; }пуф! Теперь (без моего дополнительно
<div>) он работает отлично! Ну, за исключением этого дополнительного пикселя от границ. В частности, я думаю это сочетание того, чтоclear: bothработает и правила коллапса полей, которые приводят к неожиданному макету из кода в OP.редактировать еще раз - для полной (и, я думаю, совершенно точной) истории см. отличный ответ Марка Эмери. Детали имеют некоторую сложность, что этот ответ замалчивает свыше.
в то время как Pointy показывает, как вы можете обернуть поплавки в div, в качестве альтернативы вы можете вставить пустой div между поплавками и основным разделом данных. Например:
<div style="float: left;">Left</div> <div style="float: right;">Right</div> <div style="clear: both;"></div> <div style="margin-top: 200px;">Main Data</div>Это может оказаться полезным в тех случаях, когда добавление оболочки div вокруг некоторого HTML нежелательно.
логика этого в спецификации является умопомрачительной и включает в себя сложное взаимодействие правил для клиренс и сворачивание поля.
вы, вероятно, знакомы с обычным CSS модель, в котором content box внутри padding box содержится в границы окна содержится в маржа коробка:
для элементов с
clearустановить что-то другое, чемnone, дополнительный компонент может быть введен в эту модель:клиренс.значения, отличные от "Нет", потенциально вводят клиренс. Зазор блокирует обрушение маржи и действует как расстояние над верхней частью маржи элемент.
другими словами, модель, в тех случаях выглядит примерно так:
но когда вводится разрешение, и насколько оно должно быть большим? Начнем с первого из этих вопросов. Спецификация говорит:
вычисление зазора элемента, на котором установлен 'clear', выполняется путем предварительного определения гипотетического положения верхней границы элемента край. Эта позиция - это то место, где фактический верхний край границы был бы, если бы свойство элемента "clear" было "none".
если это гипотетическое положение верхнего края границы элемента не проходит мимо соответствующих поплавков, то вводится зазор, и поля сворачиваются в соответствии с правилами в 8.3.1.
давайте применим эту логику к коду вопроса Аскера. Помните, что мы пытаемся объяснить положение третьего div в коде ниже (фоны добавлены, чтобы помочь в визуализации):
<div style="float: left; background: red;">Left</div> <div style="float: right; background: green;">Right</div> <div style="clear: both; margin-top: 200px; background: blue;">Main Data</div>давайте представим, как нас просит спецификация, что
clearустановлено значениеnoneна третьем div, вместоboth. Тогда как будет выглядеть фрагмент выше?<div style="float: left; background: red;">Left</div> <div style="float: right; background: green;">Right</div> <div style="clear: none; margin-top: 200px; background: blue;">Main Data</div>вот, третий div перекрытие два плавучих дива. Но, подождите, почему это так? Конечно, допустимо, чтобы плавающие элементы перекрывали блочные (в соответствии с плавает spec, " поскольку поплавок не находится в потоке, непозиционные блок-боксы, созданные до и после поплавка, текут вертикально, как если бы поплавок не существовал."), но наш третий div имеет множество
margin-topна нем и приходит после двух плавающих дивов; разве два плавающих дива не должны появляться в верхней части тела, а третий div появляется на 200px вниз, значительно ниже их?причина, по которой это не происходит, заключается в том, что поле третьего div рушится в край родителя divs (в этом случае тело - но то же самое поведение происходит, если вы обернете все три divs в родительский div). Элемент сворачивание спецификации полей (цитируется ниже с несколькими несущественными деталями, опущенными) говорит нам, что:
соседние вертикальные поля свернуть...
два поля смежно, если и только если:
- оба принадлежат к блок-уровню в-подачи поля, которые участвуют в том же контексте форматирования блока
- никакие линейные коробки, никакой зазор, никакая прокладка и никакая граница не отделяют их ...
- оба принадлежат к вертикально-смежных краев коробки, т. е. образуют одну из следующих пар:
- верхний край коробки и верхний край ее первого дочернего элемента
- ...
третий div в нашем примере, конечно, не является телом первый ребенок, но это его первый in-flow ребенок. Обратите внимание, что за https://www.w3.org/TR/CSS22/visuren.html#positioning-scheme:
элемент называется из потока если он плавает, абсолютно позиционируется или является корневым элементом. Элемент называется in-flow если это не вне потока.
С первого и второго div в наш пример плавает, только третий div находится в потоке. Таким образом, его верхний край примыкает к верхнему краю его родителя, и края коллапсируют - толкая вниз все тело,в том числе два плавающих элемента. Таким образом, третий div перекрывает своих братьев и сестер, несмотря на наличие большого
margin-top. Следовательно - в этом гипотетическом случае, где третий элементclearустановлено значениеnone- мы удовлетворяем условию, что:верхний край границы элемента не является мимо соответствующих поплавков
таким образом:
вводится клиренс, и поля сворачиваются согласно правилам в 8.3.1
сколько клиренс? Спецификация дает браузеру два варианта, с парой уточняющих Примечаний:
тогда величина зазора устанавливается на большее из:
- количество необходимое для того чтобы установить край границы блока даже с нижним наружным край самого нижнего поплавка, который должен быть очищен.
- сумма, необходимая для размещения верхнего пограничного края блока в его гипотетическом положении.
кроме того, зазор ровно на сумму, необходимую для размещения границы блока, даже с нижним внешним краем самой низкой поплавка, который должен быть очищен.
Примечание: оба поведения разрешены до оценки их совместимость с существующим веб-контентом. Будущая спецификация CSS потребует либо того, либо другого.
Примечание: зазор может быть отрицательным или нулевым.
прежде чем мы сможем начать применять эти правила, мы сразу же столкнемся с осложнением. Помните, что рушится маржа, которую мы должны были учитывать в гипотетическая случае
clearбылnone? Ну, это не существуют в этом не гипотетическая случай, когда мы вычисляем зазор для использования, потому что существование зазора препятствует ему. Напомним,сворачивание правил маржи из 8.3.1, процитированные ранее, диктуют, что поля только смежно если:
- никаких линейных ящиков,без оформления, их не разделяет ни обивка, ни граница
(курсив добавлен.) Таким образом, верхняя граница Третьего div и верхняя граница его родителя больше не соприкасаются. Мы можем смоделировать этот сценарий предварительной очистки в нашем примере фрагмента, сохраняя
clear: noneно при добавленииpadding-top: 1pxк телу, которое также отключает крах поля, согласно правилу, приведенному выше.body { padding-top: 1px; }<div style="float: left; background: red;">Left</div> <div style="float: right; background: green;">Right</div> <div style="clear: none; margin-top: 200px; background: blue;">Main Data</div>теперь, в отличие от того, когда поля были свернуты, наш третий div удобно расположен ниже своих двух плавающих братьев и сестер. Но мы уже решили, исходя по гипотетическому сценарию, где поля сделал коллапс, что зазор должен быть добавлен, все, что остается, это выбрать в сумме зазор, для того, чтобы:
поместите край границы блока даже с нижним внешним краем самого низкого поплавка, который должен быть очищен
и поэтому у нас нет выбора, кроме как применить отрицательный зазор к третьему div, для того чтобы волочить свою верхнюю часть границы до касания дна внешний край (также известный как маржа края) плавающих над ним элементов. Таким образом, если плавающие элементы каждый 10px высокий и третий div имеет 200px верхнего края,- 190px зазора будет применяться. Это, наконец, приводит нас к конечному результату, который видит вопрос asker:
<div style="float: left; background: red;">Left</div> <div style="float: right; background: green;">Right</div> <div style="clear: both; margin-top: 200px; background: blue;">Main Data</div>(обратите внимание, что если вы проверяете третий div В приведенном выше фрагменте, используя ваш инструменты разработчика браузера, вы все равно сможете увидеть 200px верхнего поля над div, выходя выше всего остального контента - это просто то, что вся коробка маржи была поднята вверх большим отрицательным зазором.)
просто!
Pointy и Рэндалл Кук имеют отличные ответы. Я думал, что покажу еще одно решение.
<div style="float: left;">Left</div> <div style="float: right;">Right</div> <div style="float: left; clear: both; margin-top: 200px;">Main Data</div>Если вы сделаете 3-й элемент " float: left; "и" clear: both;", он должен иметь желаемый эффект предоставления 3-му элементу поля 200 пикселей. Вот это ссылке к примеру.
Это также может повлиять на другие последующие элементы относительно того, должны ли они быть поплавками или нет. Однако это также может иметь желаемый эффект.
альтернативное решение:
вы можете на самом деле поставить
margin-bottomна плавающие элементы нажать Вниз элемент под этим имеетclear: both.
Примечание: сделав это предложение, я должен немедленно отказаться от него, как не всегда хорошая идея, но в некоторых ограниченных ситуациях может потребоваться;
<div class='order'> <div class='address'> <strong>Your order will be shipped to:</strong><br> Simon</br> 123 Main St<br> Anytown, CA, US </div> <div class='order-details'> Item 1<br> Item 2<br> Item 3<br> Item 4<br> Item 5<br> Item 6<br> Item 7<br> Item 8<br> Item 9<br> Item 10<br> </div> <div class='options'> <button>Edit</button> <button>Save</button> </div> </div>панель с элементами называется
order-detailsС этим css.order-details { padding: .5em; background: lightsteelblue; float: left; margin-left: 1em; /* this margin does take effect */ margin-bottom: 1em; }в приведенной выше скрипке-желтая панель имеет
margin-top, но если он не больше, чем самый высокий плавающий элемент, то он ничего не будет делать (конечно, в этом весь смысл этого вопроса).если вы выберите
margin-topжелтой панели до 20em, то он будет виден, потому что поле рассчитывается из верхней части внешнего синего окна.
вместо этого используйте "padding-top" в своем основном div данных. Или, в качестве альтернативы, оберните основные данные div в один с "padding-top".
попробуйте установить нижний край на одном из плавающих элементов. Кроме того, вы можете обернуть поплавки в родительский элемент и использовать CSS hack to очистить без дополнительной разметки.
иногда сочетание относительной позиции и маржи может решить эти проблемы.
Я использую эту технику для моих классов alignright и alignleft в WordPress.
например, если я хочу "нижний край", который соблюдается путем очистки элементов, которые вы можете использовать.
.alignright{ float: right; margin-left: 20px; margin-top: 20px; position: relative; top: -20px; }для вашего примера, вы могли бы сделать что-то вроде
<div style="float: left;">Left</div> <div style="float: right;">Right</div> <div style="clear: both; margin-bottom: 200px; position: relative; top: 200px;">Main Data</div>



Comments