Skip to content

Latest commit

 

History

History
executable file
·
44 lines (27 loc) · 7.51 KB

shrink-to-fit.md

File metadata and controls

executable file
·
44 lines (27 loc) · 7.51 KB

Алгоритм автоматического определения ширины shrink-to-fit в CSS

Как известно, в верстке всегда лучше стараться не указывать конкретные размеры, а использовать возможности CSS по автоматическому их подбору. Ну к примеру, нам не нужно указывать высоту каждого абзаца - браузер автоматически подбирает ее по высоте текста, который содержится в нем, с учетом полей (паддингов).

В случае с высотой все довольно просто - практически для любых типов элементов и способов позиционирования, если высоту не указать, то она определеятся содержимым элемента. А что, если мы не будем указывать явно ширину или поставим width: auto? Для разных способов позиционирования результат будет разный (напомню, что способ позиционирования задается свойствами display, float, position).

  • У замещаемых (replaced) элементов (например, картинок или кнопок) с внутренними размерами по умолчанию ширина определяется этим внутренним размером. То есть у картинки шириной 400px ширина по умолчанию будет равна этим 400px независимо от того, стоит ли у нее display: inline или float: left.
  • У обычных inline блоков, как известно, своей ширины нет и задать ее нельзя, их размер определяется текстом, на который они "натянуты"
  • Элементы с display: block по умолчанию занимают всю доступную ширину родителя за вычетом маргинов
  • У элементов таблиц (ячеек) ширина определяется по хитрым алгоритмам, так, чтобы всем хватило места. Для самой таблицы (или элемента с display: table) используется алгоритм shrink-to-fit
  • У абсолютно позиционированных элементов, у которых заданы left и right одновременно, ширина определяется через них
  • У остальных абсолютно позиционированных элементов (position: absolute, position: fixed), float элементов, элементов с display: inlibe-block ширина определяется из ширины содержимого и родителя по алгоритму shrink-to-fit

Если высоту или ширину задать явно свойством width: Npx (кроме не-замещаемых элементов с display: inline, у которых нет собственных размеров), используется указанное значение, независимо от того, вмещается в нее содержимое или нет и есть ли столько места в родительском элементе. Что будет с содержимым, которое не уложилось в явно заданные размеры, определяется свойством overflow (по умолчанию это содержимое "вылезет" за пределы блока).

Алгоритм shrink-to-fit

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

Ширина элемента определяется таким образом:

  • сначала вычисляется максимально возможная ширина содержимого - maxContentWidth. Ну например, если у нас внутри элемента содержится абзац текста, то текст записывается в одну длинную строчку без переносов и вычисляется ширина. Если абзацев несколько, то берется самый широкий. Если содержимое - не текст, а какие-то блоки с заданной шириной, берется максимальная из них. В общем, определяется какую максимальную ширину может занять содержимое, если его не ограничивать.
  • затем считается минимально возможная ширина содержимого - minContentWidth. Если содержимое - это текст, то в нем ставятся переносы строки после каждого слова и считается ширина самого длинного слова. Это минимальная ширина, меньше которой элемент сжать нельзя.
  • наконец, берется ширина родителя - parentWidth

Итоговая ширина определяется по такой формуле: width = max(minContentWidth, min(maxContentWidth, parentWidth)).

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

Пример

Допустим, у нас есть блок с float: left, и внутри него текст. Если этот текст записать в одну строку то получается строка длиной 1000px, а если делать переносы после каждого слова, то минимально возможная ширина равна 150px.

  • внутри родителя с шириной 2000px блок растянется на максимально возможную ширину - 1000px
  • внутри родителя с шириной 500px блок займет всю доступную ширину - 500px. Текст при этом будет переноситься
  • если ширина родителя очень маленькая, 50px - то блок ужмется до минимально возможной ширины 150px, таким образом, выйдя за границу родителя

Ссылки

Способы автоматического выбора ширины и высоты элемента описаны в стандарте CSS: