it-swarm.com.ru

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

Хотя такие элементы, как <div>s, обычно растут в соответствии со своим содержимым, использование свойства 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>

Плюсы: прямо к коду.
Минусы: Не семантически; spacer 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.

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

956
Nathan Long

Решение 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.

514
A.M.K

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

71
Bobby Jack

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

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

div {
  overflow:hidden;
}

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

19
tybro0103

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

  • { clear: both; }
  • 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%;
}

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

18
Sarfraz

Существует несколько версий исправления: Николас Галлахер и Тьерри Кобленц в качестве ключевых авторов.

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

.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;
}
14
John Slegers

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

.clear 
{
   clear: both;
}

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

9
Bryan A

Странно, еще никто не придумал полного ответа на это, ну что ж, вот оно.

Решение первое: ясно: оба

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

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

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

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

Решение второе: display: table

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

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

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

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

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

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

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

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

Неверный CSS

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

В заключение

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

9
lededje

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

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

9
DisgruntledGoat

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

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

6
Konrad Rudolph

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

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

.clearfix {
    display: inline-block;
}

* html .clearfix {
    height: 1%;
}

.clearfix {
    display: block;
}
5
Christian Gray

Одним из наиболее известных решений является вариант вашего решения № 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;
}
4
banzomaikaka

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

 <div style="clear:both"></div>
3
Leons Kalapurakal

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

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

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

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

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

2
Jonathan

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

2
cssisashtandw3tooo

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

Вот почему:

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

2) overflow должен делать что-то еще, поэтому этот хак недостаточно надежен.

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

0
jave.web