Как использовать CSS float, не скрывая части DIV

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

<html>

<div style="width:400px">

<div style="width:150px;float:right;border:thin black solid">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam.</div>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 

<div style="background-color:red;border:thin black solid">Some sample text</div>

Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
</div>

</html> 

Если вы вставите этот HTML-код в браузер (или просмотрите его jsfiddle), вы заметите, что "Некоторый образец text" красного цвета, и красный фон распространяется на весь плавающий DIV. Хотя я уверен, что есть способ скрыть части красного фона, которые мне не нужны, он все равно оставит границу обрезанной и скрытой под DIV. В идеале я хочу, чтобы цвет фона и граница занимали только допустимое текстовое пространство и не ползали под плавающим DIV. Возможен ли этот эффект?

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

Вот что я получаю:

Плохо

Это то, что я хочу:

Хорошо

Вы заметите, что в обоих примерах окончательный текст обтекает плавающую часть по мере того, как текст достигает нижней части. Мой второй пример, который я могу получить, напрямую указав ширину div, содержащего «Некоторый образец текста». Я не хочу указывать ширину. Это кажется излишним, так как я хочу, чтобы ширина текста была такой же, как у текста вокруг него. Но, может быть, это невозможно?


person Kirk Woll    schedule 14.10.2009    source источник
comment
Я хочу присудить награду за ответ, в котором прямо говорится, что это невозможно, потому что этому ответу (который закрывает дебаты) не уделяется достаточно внимания, а ответ с максимальным количеством голосов... не отвечает на вопрос.. , хотя он предоставляет ценную информацию   -  person Samuel Rossille    schedule 10.04.2013
comment
@SamuelRossille: я не уверен, что мне здесь не хватает (изображения выше больше не показывают желаемого). Я разместил несколько ссылок на скрипку под принятым ответом (в настоящее время ответ Кирка Уолла), которые, казалось бы, указывают на то, что ответ Клетуса был правильным (текст все еще переносится под правым поплавком). Возможно, в старых браузерах было другое поведение (этой теме более трех лет).   -  person ScottS    schedule 10.04.2013
comment
@ScottS, да, извини. Это было еще в плохие времена, когда у SO не было собственного внутреннего решения для размещения изображений. Я пытался посмотреть, смогу ли я восстановить эти изображения, но безрезультатно.   -  person Kirk Woll    schedule 11.04.2013
comment
@KirkWoll: Это понятно. Не могли бы вы прокомментировать мои комментарии под вашим ответом? Я не знаю, чего вы пытались достичь (надеюсь, вы помните это из далекого прошлого), но похоже, что ответ Клетуса был на самом деле тем, что вы искали (по крайней мере, как его интерпретируют современные браузеры). Но я мог что-то упустить здесь.   -  person ScottS    schedule 11.04.2013


Ответы (6)


Если вы добавите span в свой div и добавите такой стиль (конечно, обычно я бы не использовал встроенный стиль):

<div style="overflow: hidden;">
  <span style="background-color:red;
               border:thin black solid;
               display: inline-block;">
   Some sample text
   </span>
</div>

Затем вы можете получить эффект, показанный в этой скрипте. Обратите внимание, что overflow:hidden на самом div предназначено для переноса строк для длинных текстовых строк.

person ScottS    schedule 14.04.2013
comment
Это был фактический ответ, который я искал, задавая вопрос. Хорошая работа. - person Kirk Woll; 19.04.2013
comment
Я рад, что смог дать вам то, что вы искали (даже спустя два года). - person ScottS; 19.04.2013
comment
Лучше поздно, чем никогда! :) - person Kirk Woll; 19.04.2013
comment
@KirkWoll Имейте в виду, что если текст станет достаточно длинным, чтобы потребовать переноса, он нарушит макет, поскольку будет перемещен ниже правого поля jsfiddle.net/gaby/MS5z5/2 - person Gabriele Petrioli; 19.04.2013
comment
@KirkWoll решением было бы использовать :before и :after для создания новых строк, но вы все равно не можете правильно оформить границу для многострочных. jsfiddle.net/gaby/MS5z5/4 - person Gabriele Petrioli; 19.04.2013
comment
@GabyakaG.Petrioli: На самом деле, простое добавление overflow: hidden к оболочке div решает проблему переноса строк. Я обновил свою ссылку на скрипку в ответе выше на это исправленное решение и показал изменение кода . - person ScottS; 19.04.2013

Вот одно из решений:

<div style="background-color:red;border:thin black solid;overflow:hidden;">Some sample text</div>

В основном магия здесь overflow: hidden, которая изменяет модель визуального форматирования CSS. Взгляните на основы компоновки CSS, часть 5: плавающие элементы:

Фиксация соседних коробок

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

Исправление этой проблемы находится в очень хорошо скрытом абзаце в разделе floats спецификации CSS 2.1:

Рамка таблицы, замененный элемент на уровне блока или элемент в обычном потоке, который устанавливает новый контекст форматирования блока (например, элемент с "переполнением", отличным от "visible") не должен перекрывать какие-либо плавающие элементы в том же контексте форматирования блока, что и сам элемент.

Таким образом, чтобы блок абзаца не перекрывался с плавающим содержимым, решением является создание «нового контекста форматирования блока» в терминологии авторов спецификаций CSS. Звучит сложно, а? К счастью, это не так сложно. Новые контексты форматирования блока создаются любым блоком, отвечающим следующим критериям:

  • плавает
  • абсолютно позиционирован
  • имеет значение свойства отображения одного из более необычных вариантов (встроенный блок, табличная ячейка и т. д.)
  • имеет свойство overflow, установленное в значение, отличное от visible.

Последний вариант проще всего сделать в большинстве случаев: установка overflow: auto для нашего абзаца создаст новый «контекст форматирования блока» и отобразит границу абзаца в нужном месте.

person cletus    schedule 14.10.2009
comment
Спасибо, но это не позволяет тексту в левом столбце переноситься в пространство справа, когда плавающий элемент div завершен. - person Kirk Woll; 15.10.2009
comment
Ничто не позволяет этого. Вы можете обернуть текст вокруг правого плавающего элемента, но это также расширит блочный элемент вправо. Блочный элемент по определению является квадратом, и вам, кажется, нужен квадрат с вырезом в правом верхнем углу и границей, следующей за этой линией. Не могу этого сделать. - person cletus; 15.10.2009
comment
Это то, чего я боялся, но спасибо за откровенность. :) - person Kirk Woll; 15.10.2009
comment
Работал на меня, @cletus. Спасибо! - person Karim; 04.11.2009

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

(Я проголосовал за ответ Клетуса, но не хотел отмечать его как правильный «ответ», потому что считаю, что будущие гуглеры должны быть быстро разочарованы.)

person Community    schedule 24.11.2010
comment
Возможно, я что-то упускаю, но ответ @Cletus, похоже, работает так, как вы хотите, в этой скрипте и вот этот. - person ScottS; 10.04.2013
comment
@ScottS, хм, скрипка в вашем втором комментарии - это именно то, чего я всегда жаждал. Если вы опубликуете это как ответ, я хотел бы отметить его как правильный ответ. (на самом деле, так рад, я бы с удовольствием наградил его наградой — разве это не именно то, что мы ищем, Сэмюэл?) - person Kirk Woll; 12.04.2013
comment
Добавил ответ, основанный на моей скрипке во втором комментарии. - person ScottS; 14.04.2013

Вы должны указать другой столбец как float left. В том виде, в каком вы это сделали сейчас, текст слева будет обертывать плавающий текст справа. Также было бы разумно указать размер плавающего объекта слева.

<html>

<div style="width:400px">

<div style="width:150px;float:right;border:thin black solid">
     Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim  veniam.</div>

     Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 

<div style="background-color:red; width: 250px; border:thin black solid">Some sample text

     Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
</div></div>

</html>

Кроме того, рассмотрите возможность использования CSS, это значительно облегчит поддержку этого кода в долгосрочной перспективе‹‹.

EDIT: я думал, что вы хотите, чтобы все было смещено влево. Думаю, я неправильно понял ваш вопрос. То, что вы пытаетесь сделать, невозможно. Лучшее, что вы можете сделать, это либо указать поле объекта, плавающего вправо, равное 400-150 (250 пикселей), либо указать ширину объекта «какой-то текст», равный (250 пикселей).

person slimbo    schedule 14.10.2009
comment
Спасибо, но это не позволяет тексту в левом столбце переноситься в пространство справа, когда плавающий элемент div завершен. - person Kirk Woll; 15.10.2009
comment
Кроме того, использование наборов стилей показалось бы мне бесполезным в вопросе о переполнении стека. :) - person Kirk Woll; 15.10.2009
comment
Хорошо, я ценю ответ. В качестве примера того, почему это досадно, ознакомьтесь со статьей в Википедии: en.wikipedia.org/wiki /Автоматизированное_программирование. Вы заметите, что пример традиционной (императивной) программы окружен приятной рамкой, как я пытался описать здесь. К сожалению, они столкнулись с точно такой же проблемой, и вы заметите, что правый край окна полностью отсутствует, потому что он скрыт под полезным плавающим навигационным блоком справа. Иногда HTML/CSS заставляет Иисуса плакать. - person Kirk Woll; 17.10.2009
comment
Ха-ха, мне жаль, что я не мог больше помочь. Как и в любом языке программирования, всегда есть ограничения. Если бы их не было, мы бы использовали один язык программирования для всего. Удачи :) - person slimbo; 18.10.2009

Я думаю, что вам нужно сделать только одну вещь:

  • Дайте div "sample text" правое поле, большее, чем ширина плавающего справа элемента

Это должно сработать.

Редактировать. Основываясь на ваших изменениях, я предлагаю вам использовать span (встроенный элемент) вместо div (блочный элемент). Если вам всегда нужно, чтобы он находился на отдельной строке, вы можете указать как для этого элемента, так и для элемента после него значение clear:left.

person jeroen    schedule 14.10.2009
comment
Это, вероятно, сработает, но это будет означать, что каждый раз, когда мне нужно маленькое красное информационное поле, я должен явно указывать ширину. Это звучит очень болезненно. - person Kirk Woll; 15.10.2009
comment
Спасибо за ваш ответ, но, к сожалению, вы не можете растянуть ширину до границ окружающего текста. т. е. цвет границы и фона будет окружать только текст, который вы вводите (останавливаясь в конце текста в некотором образце текста), но не заполняет весь путь до правого края (где появляется начало плавающего элемента div). - person Kirk Woll; 17.10.2009

Я узнал об этом вопросе так поздно, так или иначе, я исправляю вашу проблему. См. этот Fiddle

Вам нужно определить display: table;

Как это:

<div style="background-color:red;border:thin black solid;display: table;">Some sample text</div>

Примечание display: block; не работает как display: table;, и вы также можете использовать display: table-cell;

Вам также может понравиться этот вопрос: css inline-block vs table-cell

person Bhojendra Rauniyar    schedule 19.04.2013
comment
просто для справки - если вы читали сообщение Bounty: автор создал его, чтобы вознаградить за принятый ответ, а не все еще ищет ответ. - person Jesse; 19.04.2013
comment
@ Джесси- Да! Я знаю, что так я сказал поздно узнал. Но ответ поможет будущим читателям, поэтому я ответил. - person Bhojendra Rauniyar; 20.04.2013