Почему встроенные блоки ломаются после неразрывного пространства?
Некоторые HTML-коды:
<p id='one'>Hello World how are you. <span>Entrepreneur</span></p>
<p>Hello World how are you. <span>Entrepreneur</span></p>
Некоторые CSS:
#one span {
display: inline-block;
}
p {
font-family: Arial;
font-size: 16px;
width: 200px;
}
Второй абзац ведет себя так, как я ожидаю.
Первое, однако, ведет себя по-разному, из-за того, что span является встроенным блоком.
Мой вопрос: почему диапазон inline-block
игнорирует строку
и прерывает строку между span
и предыдущим словом?
Спасибо!
Пример скрипта здесь.
Ответы
Ответ 1
Итак, похоже, что поведение несовместимо в разных браузерах:
-
В IE11 и последних нескольких версиях я смог проверить это, независимо от того, является ли span
встроенным ящиком или блоком встроенного блока, IE уважает свободное пространство и не разделяет span
из предыдущего слова.
-
Во всех других браузерах поведение такое же, как описано в вопросе. Безразрывное пространство, как представляется, игнорируется, когда span
является встроенным блоком; вместо этого он становится вынужденным на свою линию и отделен от предыдущего слова. Обратите внимание, что пространство без разрыва все еще существует; он появляется в конце первой строки сразу после слова, что можно увидеть, выделив строку в Firefox.
Объяснение, данное некоторыми другими, здесь выглядит довольно звуковым: встроенный блок отформатирован как блок-блок, за исключением встроенной строки, поэтому это может быть причиной того, что он не всегда ведет себя так же, как встроенный блок. Однако я не смог найти ничего в спецификации, которая подтверждает это. Также не объясняет, почему IE ведет себя так, как это делает, или действительно, работает ли IE неправильно или просто по-другому.
В спецификации CSS2.1 указано следующее в разделе 9.2.2, которое хорошо объясняется приведенным выше объяснением:
Ящики встроенного уровня, которые не являются встроенными блоками (например, замененными элементами линейного уровня, элементами встроенного блока и элементами inline-table), называются атомарными ящиками на уровне строки, поскольку они участвуют в их встроенном контексте форматирования как единый непрозрачная коробка.
Но он не полностью описывает взаимодействие между разрывами строк и атомными строчными шкафами, не говоря уже о эффекте, которое не имеет места для этого взаимодействия. Поэтому, к сожалению, не представляется достаточным объяснением поведения любого браузера.
Я даже просмотрел текстовый модуль CSS3, но все, что он должен сказать в отношении разрывов строк и атомных строк, this:
- Поведение нарушения строки замененного элемента или другого атомарного inline эквивалентно поведению символа замены объекта (U + FFFC).
... и когда я пытаюсь использовать U + FFFC, результаты полностью ненадежны:
<p id='one'>Hello World how are you. <span>Entrepreneur</span></p>
<p>Hello World how are you. <span>Entrepreneur</span></p>
<p>Hello World how are you. </p>
А именно:
-
IE ведет себя наиболее последовательно, разбивая все три абзаца одинаково.
-
Firefox прерывает строку с символом так же, как и второй абзац, учитывая пространство без разрыва.
-
Chrome даже не пытается отобразить символ.
Возможно, я просто неправильно понимаю цитату из текстового модуля CSS3, возможно, браузеры не выполняют определенные контрольные символы правильно, я не могу сказать наверняка. Но, во всяком случае, я начинаю сомневаться, что это поведение действительно определено в любой спецификации CSS вообще.
Ответ 2
В спецификациях нет строгого ответа, поскольку спецификации HTML и CSS не определяют точные правила для разрыва строки. HTML 4.01 говорит: "Иногда авторам может потребоваться предотвратить разрыв строки между двумя словами. Объект
( 
или  
) действует как пространство, в котором пользовательские агенты не должны вызывать разрыв строки." Но на самом деле это не требует, чтобы браузеры подчинялись этому.
Браузеры, которые не рассматривают
как предотвращение разрыва строки перед встроенным блоком, могут это оправдать, заявив, что
просто обозначает символ NO-BREAK SPACE *, который определен (в Unicode) как предотвращающий разрывы строк, когда он появляется между символами. Здесь он находится между символом и элементом встроенного блока, который (неофициально говоря) воспринимается как черный ящик в форматировании строк, т.е. Занимает некоторое пространство, но не рассматривается как символ или как содержащий символы.
Обратите внимание, что ситуация аналогична, если вы удалите
. Строка типа "you.Entrepreneur" не нарушена, но если вы сделаете "Предприниматель" встроенным блоком, строка может сломаться.
Аналогичные соображения применимы к изображениям. Браузеры не могут почитать
между текстом и изображением, потому что здесь также невозможен ПРОБЕЛ NO-BREAK между символами.
Вы все же можете предотвратить разрывы строк, но вам нужно быть более явным, например.
<p>Hello World how are <nobr>you. <span>Entrepreneur</span></nobr></p>
Im использует nobr
в примере для простоты. Вместо этого вы можете использовать стандартный элемент и установить для него white-space: nowrap
(это свойство CSS, несмотря на его имя, влияет не только на обработку пробелов, но и на этот параметр, предотвращает разрывы строк в контенте).
Ответ 3
Я бы предположил, что это связано с тем, что внутристрочный блок визуализирует внутреннюю часть элемента как блока. Поскольку у вас нет пробела между текстом и диапазоном, он заставляет перерыв, а затем отбрасывает его на другую строку.
Не заметил этого раньше, хотя в основном это предположение.
Ответ 4
Единственное, что я могу найти, это
Согласно https://developer.mozilla.org/en-US/docs/Web/CSS/display
Для встроенного блока
Элемент создает блок-блок, который будет протекать с окружающим контентом, как если бы он был одним встроенным ящиком (вел себя как замененный элемент)
рядный
Элемент генерирует один или несколько встроенных блоков элементов.
Я предполагаю, что поскольку inline-block
генерирует элемент блока, так что неиспользуемое пространство не работает так, как ожидалось, когда пролет обычно равен inline