Нужно объяснить, почему установка правильного плавающего элемента в качестве первого элемента в div устраняет проблему с новой строкой - PullRequest
1 голос
/ 13 августа 2010

У меня есть div с несколькими элементами, и последний элемент - это кнопка, которую я хотел расположить в 10 пикселях от правого края div. Div и кнопка имеют фиксированную ширину. Кнопка имеет индикацию: inline (с учетом того, что плавающие элементы получают поведение блока). Проблема заключалась в том, что правильное плавание кнопки всегда помещало кнопку в новую строку, даже если в div было достаточно места.

Простым решением, которое я нашел, было размещение кнопки в качестве первого элемента в div. Работало в IE6, 7, 8 и FF. Мне интересно, ожидается ли такое поведение в стандартах CSS?

Ни в одной из книг по CSS я не упомянул этот маленький трюк, или он мне не понравился. Я ценю, если кто-то может сослаться на книгу или сайт, который объясняет это поведение.

Дополнительно: Контейнерные дивы используют эту CSS для хранения дочерних элементов

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

Ответы [ 3 ]

7 голосов
/ 14 августа 2010

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

Пример кода

<!DOCTYPE HTML>
<html><head><title>Float Tests</title></head>
<style>
.parent { border: 1px solid #00ddaa; margin-bottom: 5em; }
.float { border: 1px solid #dd00bb; float: right; }
.clear { clear: both; }
p { margin: 0; }
</style>
<body>

<div class="parent">
<p class="float">Paragraph 1</p>
<p>Paragraph 2</p>
<p>Paragraph 3</p>
<div></div>
</div>

<div class="parent">
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<p class="float">Paragraph 3</p>
<div></div>
</div>

<div class="parent">
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<p class="float">Paragraph 3</p>
<div class="clear"></div>  <!-- We're clearing this time -->
</div>

</body></html>

Render

Float Render http://media.banzaimonkey.net/images/forums/floats.png

Анализ

В первом примере p1 является плавающим.p1 перемещается вправо, но нижний край p1 не блокируется относительно p2, поэтому p2 скользит вверх, чтобы заполнить пустое пространство.

Во втором примере p3 является плавающим.p3 перемещается вправо, но нижний край абзаца не блокируется относительно нижнего края родительского div, поэтому border скользит вверх, чтобы заполнить пустое пространство.Это приводит к тому, что абзац появляется за пределами div.

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

Так что же здесь происходит?

Что на самом деле float позволяет элементам ниже это обтекать его содержимое.Причудливо, он также позволяет свернуть блоки вокруг него.

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

Так почему же параграф 3 не всплывает наверхродительский контейнер?Потому что абзацы 1 и 2 заполняют всю ширину родительского контейнера.Если вы хотите, чтобы второй и третий абзацы были в одной строке, вам придется переместить второй абзац влево, например, так:

<div class="parent">
<p>Paragraph 1</p>
<p class="float" style="float: left;">Paragraph 2</p>  <!-- Float left -->
<p class="float">Paragraph 3</p>
<div class="clear"></div>
</div>

Что выглядит как:

Два плавания http://media.banzaimonkey.net/images/forums/floats2.png

Сводка

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

0 голосов
/ 14 августа 2010

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

ДЕМО

0 голосов
/ 14 августа 2010

Все довольно странно, когда браузер работает в режиме причуд, по крайней мере, в IE.Если вы укажете строгий DTD, все будет работать так, как вы ожидаете в IE 8, FF 3.6.4 и Chrome 5. (В Chrome это работало в любом случае, но добавление типа документа не помешало.) Я не могу сказать оIE 6 или 7 - я ими не пользуюсь и не могу без покупки большего количества компьютеров или создания этого нестабильного, поэтому я не намеренно их поддерживаю.

Тестовая страница, которую я использовал:

<div style="width: 300px; border: 1px solid black">
 Some text
 <input type="button" 
       style="float: right; width: 50px; margin-right: 10px"
       value="test">
</div>

Без типа документа кнопка появляется в следующей строке в IE 8. После добавления <!DOCTYPE html> вверху страницы она появляется в той же строке.

Старые версииIE не знает о HTML 5, поэтому строка выше doctype должна быть полностью HTML 4 строгой или , может быть переходной.Даже тогда это может быть ненадежно в старых браузерах, и, как я уже сказал, я не могу проверить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...