Как вы удерживаете родителей всплывающих элементов от разрушения? [Дубликат]

883

Несмотря на то, что такие элементы, как <div>, обычно растут, чтобы соответствовать их содержимому, использование свойства float может вызвать потрясающую проблему для новичков CSS: , если в элементах с плавающей точкой есть неоплачиваемые родительские элементы, родительский член скроется.

Например:

  <div>
        <div style="float: left;">Div 1</div>
        <div style="float: left;">Div 2</div>
    </div>

Родительский div в этом примере будет не развернуть, чтобы содержать его плавающих дочерних элементов - он будет иметь height: 0.

Как вы решаете эту проблему?

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

Решение 1

Поплавьте родителя.

  <div style="float: left;">
        <div style="float: left;">Div 1</div>
        <div style="float: left;">Div 2</div>
    </div>

Профи: семантический код.
Минусы. Возможно, вы не всегда хотите, чтобы родительский плавал. Даже если вы это сделаете, вы плаваете родительский родитель и так далее? Должен ли вы плавать каждый элемент предка?

Решение 2

Дайте родителю явную высоту.

    <div style="height: 300px;">
        <div style="float: left;">Div 1</div>
        <div style="float: left;">Div 2</div>        
    </div>

Профи: семантический код.
Минусы: не является гибким - если содержимое изменяется или изменяется размер браузера, макет будет разорван.

Решение 3

Добавить элемент "spacer" внутри родительского элемента, например:

    <div>
        <div style="float: left;">Div 1</div>
        <div style="float: left;">Div 2</div>
        <div class="spacer" style="clear: both;"></div>
    </div>

Профи: Простой код.
Минусы: не семантический; разделитель div существует только как макет.

Решение 4

Задайте родительский элемент overflow: auto.

   <div style="overflow: auto;">
        <div style="float: left;">Div 1</div>
        <div style="float: left;">Div 2</div>        
    </div>

Плюсы: не требует дополнительного div.
Минусы: Похоже на хак - это не свойство overflow, указанное в заявлении.

Комментарии? Другие предложения?

  • 32
    Я не знал о переполнении: авто трюк - я всегда использовал метод очистки div. Спасибо за чаевые.
  • 6
    Совет: Решение 4 похоже работает для Firefox 3+, но не для IE7. Для этого вам нужно решение 3
Показать ещё 17 комментариев
Теги:
css-float
layout
clearfix

16 ответов

486

Решение 1:

Самый надежный и ненавязчивый метод выглядит следующим образом:

Демо: http://jsfiddle.net/SO_AMK/wXaEH/

HTML:

<div class="clearfix">
    <div style="float: left;">Div 1</div>
    <div style="float: left;">Div 2</div>
</div>​

CSS:

.clearfix::after { 
   content: " ";
   display: block; 
   height: 0; 
   clear: both;
}

При небольшом таргетинге CSS вам даже не нужно добавлять класс к родительскому DIV.

Это решение обратно совместимо с IE8, поэтому вам не нужно беспокоиться о том, что старые браузеры не работают.

Решение 2:

Было предложено адаптироваться к решению 1 и выглядит следующим образом:

Демо: http://jsfiddle.net/wXaEH/162/

HTML:

<div class="clearfix">
    <div style="float: left;">Div 1</div>
    <div style="float: left;">Div 2</div>
</div>​

CSS:

.clearfix::after { 
   content: " ";
   display: block; 
   height: 0; 
   clear: both;
   *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML += '<div class="ie7-clear"></div>' );
}

.ie7-clear {
    display: block;
    clear: both;
}

Это решение похоже на обратную совместимость с IE5.5, но не проверено.

Решение 3:

Также возможно установить display: inline-block; и width: 100%;, чтобы эмулировать нормальный элемент блока, не сворачиваясь.

Демо: http://jsfiddle.net/SO_AMK/ae5ey/

CSS:

.clearfix {
    display: inline-block;
    width: 100%;
}

Это решение должно быть обратно совместимо с IE5.5, но было протестировано только в IE6.

  • 7
    -1 Встроенный блок со 100% имеет нежелательные эффекты, когда у вас есть заполнение этого элемента. -1: после не работает в ie6
  • 12
    @lededje: IE6 (черт, даже IE7) имеет сломанную модель с плавающей точкой, которая никогда не может быть полностью исправлена с помощью каких-либо явных исправлений.
Показать ещё 17 комментариев
70

Обычно я использую трюк overflow: auto; хотя это, строго говоря, не предназначено для переполнения, это связано с любовью - достаточно, чтобы было легко запомнить, конечно. Сам смысл float: left был расширен для различных применений более значительным, чем переполнение в этом примере, IMO.

  • 0
    Поздравляем, это именно официальное решение w3: w3schools.com/css/tryit.asp?filename=trycss_layout_clearfix
  • 15
    W3! = W3Schools, на самом деле W3Schools imho содержит очень «подозрительный» контент по отношению к стандартному HTML.
19

Вместо того, чтобы помещать overflow:auto в родительский элемент, поставьте overflow:hidden

Первый CSS, который я пишу для любой веб-страницы, всегда:

div {
  overflow:hidden;
}

Тогда мне никогда не придется беспокоиться об этом.

  • 10
    Это плохая идея. Вы не хотите ничего обрезать случайно, особенно если вы установите фиксированные размеры для этих элементов. Кроме того, существуют случаи, когда overflow: auto предпочтительнее overflow: hidden (например, вы хотите, чтобы содержимое было прокручиваемым при переполнении).
  • 1
    С тех пор, как я это опубликовал, я перестал использовать это как глобальное значение по умолчанию. Я думаю, что overflow:hidden чаще всего является лучшим решением. Каждый случай индивидуален. Спасибо что подметил это ;)
Показать ещё 2 комментария
18

Проблема возникает, когда плавающий элемент находится в контейнере, этот элемент автоматически не настраивает высоту контейнеров для перемещаемого элемента. Когда элемент перемещается, его родительский элемент больше не содержит его, потому что float удаляется из потока. Вы можете использовать 2 метода для его исправления:

  • { clear: both; }
  • clearfix

Как только вы поймете, что происходит, используйте метод ниже для "clearfix".

.clearfix:after {
    content: ".";
    display: block;
    clear: both;
    visibility: hidden;
    line-height: 0;
    height: 0;
}

.clearfix {
    display: inline-block;
}

html[xmlns] .clearfix {
    display: block;
}

* html .clearfix {
    height: 1%;
}

Демонстрация:)

  • 0
    У меня проблема с поплавками, разрушающими границу div на ie6. Я добавил height: 0 которая исправила ie6, но сломала ie7 и выше. :( Получается height: 1% исправляет ie6 и не разрушает ie7up!: D
12

Есть несколько версий clearfix, с Николас Галлахер и Thierry Koblentz в качестве ключевых авторов.

Если вам нужна поддержка старых браузеров, лучше использовать это clearfix:

.clearfix:before, .clearfix:after {
    content: "";
    display: table;
}

.clearfix:after {
    clear: both;
}

.clearfix {
    *zoom: 1;
}

В SCSS вы должны использовать следующую технику:

%clearfix {
  &:before, &:after {
    content:" ";
    display:table;
  }

  &:after {
    clear:both;
  }

  & {
    *zoom:1;
  }
}

#clearfixedelement {
    @extend %clearfix;
}

Если вам не нужна поддержка старых браузеров, там есть более короткая версия:

.clearfix:after {
    content:"";
    display:table;
    clear:both;
}
9

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

Решение первое: очистить: оба

Добавление элемента блока со стилем clear: both; на нем будут очищаться поплавки за эту точку и прекратить свертывание родительского элемента этого элемента. http://jsfiddle.net/TVD2X/1/

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

Минусы: требуется, чтобы другой тег очищал поплавки, раздувание разметки.

Примечание. Чтобы вернуться в IE6 и работать с абстинентными родителями (т.е. элементом ввода), вы не сможете использовать: после.

Решение два: display: table

Добавление отображения: таблица; для родителя, чтобы он отмахнулся от поплавков и отобразился с правильной высотой. http://jsfiddle.net/h9GAZ/1/

Плюсы: Никакой дополнительной разметки и много опрятных. Работает в IE6 +

Минусы: Требуется недопустимый css, чтобы убедиться, что все играет хорошо в IE6 и 7.

Примечание. Авторизация ширины IE6 и 7 используется для предотвращения того, чтобы ширина составляла 100% + отступы, что не имеет места в новых браузерах.

Замечание о других "решениях"

Эти исправления возвращаются к самому поддерживаемому браузеру, более 1% использования по всему миру (IE6), что означает использование: после того, как оно не вырезано.

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

Установка высоты "предотвращает" крах, но это не является правильным исправлением.

Недействительный css

Недействительный css никогда никому не повредит, на самом деле, теперь это норма. Использование префиксов браузеров столь же недействительно, как использование определенных браузером хакеров и не влияет на конечного пользователя, что когда-либо было.

В заключение

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

  • 1
    С каких пор IE6 поддерживает display: table ?
  • 0
    [rant] См. caniuse.com/#feat=css-table , для полного списка совместимости. IE 6 и 7 не поддерживают display: table; , Что касается вашего другого решения, оно уже упоминалось в вопросе, который запрашивает « Другие предложения». Пожалуйста, прочитайте вопрос и все ответы, прежде чем предоставить свой собственный ответ и понизить мнение других. Еще один момент, недействительный CSS не может никого «навредить», но это неверный CSS, независимо от того, и префиксы вендоров - это не просто принятая норма, загляните в инспектор Chrome, и вы увидите, что он не просто считает их недействительными, они не обрабатывается вообще . [/ Напыщенная]
Показать ещё 9 комментариев
9

Идеальное решение заключалось бы в использовании inline-block для столбцов вместо плавающего. Я думаю, что поддержка браузера очень хороша, если вы следуете (а) примените inline-block только к элементам, которые обычно являются встроенными (например, span); и (b) добавить -moz-inline-box для Firefox.

Проверьте свою страницу в FF2, потому что у меня было много проблем при вложении определенных элементов (что удивительно, это тот случай, когда IE работает намного лучше, чем FF).

9

Хотя код не является совершенно семантическим, я считаю более простым иметь то, что я называю "очищающим div" в нижней части каждого контейнера с поплавками в нем. Фактически, я включил следующее правило стиля в мой блок reset для каждого проекта:

.clear 
{
   clear: both;
}

Если вы разрабатываете для IE6 (бог вам помочь), вы можете также дать этому правилу высоту и высоту линии 0px.

  • 0
    если внутри вашего элемента есть что-то вроде поля «Мне нравится» на Facebook, вам нужно использовать этот метод, иначе, когда вы нажмете «Нравится», поле для комментариев на Facebook будет обрезано.
6

Я использую 2 и 4, если это применимо (т.е. когда я знаю высоту содержимого или если переполнение не наносит вреда). В любом месте, я иду с решением 3. Кстати, ваше первое решение не имеет преимущества более чем 3 (что я могу заметить), потому что он не является более смысловым, поскольку он использует тот же фиктивный элемент.

Кстати, я не буду беспокоиться о том, что четвертое решение является взломом. Взломы в CSS будут только вредными, если их основное поведение подвержено переинтерпретации или другим изменениям. Таким образом, ваш хак не будет гарантированно работать. Однако в этом случае ваш хак полагается на точное поведение, которое должен иметь overflow: auto. Не навредить свободной поездке.

  • 0
    К сожалению, я удалил фиктивный элемент в первом решении. Это была ошибка. Спасибо за указание на это.
5

Мой любимый метод использует класс clearfix для родительского элемента

.clearfix:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}

.clearfix {
    display: inline-block;
}

* html .clearfix {
    height: 1%;
}

.clearfix {
    display: block;
}
4

Одним из наиболее известных решений является вариант вашего решения номер 3, который использует псевдоэлемент вместо не-семантического элемента html.

Что-то вроде этого...

.cf:after {
    content: " ";
    display: block;
    visibility: hidden;
    height: 0;
    clear: both;
}

Вы помещаете это в таблицу стилей, и все, что вам нужно, это добавить класс 'cf' к элементу, содержащему поплавки.

Я использую еще одну вариацию, которая исходит от Николаса Галлахера.

Он делает то же самое, но он короче, выглядит более аккуратным и, возможно, используется для достижения еще одной полезной вещи, которая предотвращает крах родительских элементов с родителями (но для этого вам нужно что-то еще - читать подробнее об этом здесь http://nicolasgallagher.com/micro-clearfix-hack/).

.cf:after {
    content: " ";
    display: table;
    clear: float;
}
3

добавьте это в родительский div внизу

 <div style="clear:both"></div>
2

Возможно, этот простой пример полезен: https://github.com/imammubin/Simple-Example-Slideshow-Responsive-Layout

2

Еще одно возможное решение, которое, я думаю, более семантически корректно, заключается в изменении плавающих внутренних элементов на "display: inline" . Этот пример и то, над чем я работал, когда я сталкивался с этой страницей, использует плавающие divs точно так же, как и диапазон. Вместо использования divs, переключения на span или если вы используете другой элемент, который по умолчанию "display: block" вместо "display: inline" , затем измените его на "display: inline" . Я считаю, что это 100% семантически правильное решение.

Решение 1, плавающее родителем, по существу, должно изменить весь документ, который будет плавать.

Решение 2, устанавливающее явную высоту, похоже на рисование поля и указание, что я хочу поместить изображение здесь, то есть использовать это, если вы делаете тег img.

Решение 3, добавив разделитель, чтобы очистить float, похоже на добавление дополнительной строки под вашим контентом и будет бесполезно с окружающими элементами. Если вы используете этот подход, вы, вероятно, хотите установить div как высоту: 0px.

Решение 4, переполнение: автоматически, признает, что вы не знаете, как выложить документ, и вы признаете, что не знаете, что делать.

  • 0
    Вы хотите удалить объявление float? Потому что плавающие элементы не могут быть ничем иным, как display: block.
2

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

0

Я считаю, что лучший способ - установить clear:both на предстоящий элемент.

Вот почему:

1) :after Селектор не поддерживается в IE6/7 и багги в FF3, однако,          если вы заботитесь только об IE8 + и FF3.5 + очистке с: после, вероятно, лучше всего для вас...

2) overflow должен делать что-то еще, чтобы этот хак недостаточно надежный.

Примечание для автора: нет ничего взломанного при очистке... Очистка означает пропустить плавающие поля. CLEAR с нами с HTML3 (кто знает, может быть, даже дольше) http://www.w3.org/MarkUp/html3/deflists.html, возможно, они должны выбрать немного другое имя, например, страницу: новое, но это просто деталь...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню