Равномерное выравнивание блоков по ширине

Self Promo
Продолжая свои «css-раскопки» возникла новая идея, разобрать по косточкам ещё одну актуальную тему, которая касается равномерного выравнивания блоков по ширине. В принципе мои доскональные исследования я уже запостил у себя в блоге, но так как прошлая моя работа очень понравились Хабра-сообществу, то я решил сделать здесь небольшой краткий обзорчик этой статьи, чтобы ни одна хабра-душа не пропустили её наверняка. Так что, как говорил Гагарин: «Поехали».

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

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

Как это работает?


По сути, мы должны получить то, что делает text-align: justify с текстом. Так как поведение наших блоков уж очень напоминает результат выравнивания слов в строке с помощью именно этого свойства. Думаю многие уже примерно представляют, что это за свойство и примерную его работу.

*В этом обзоре я не стал постить разбор этапов всего алгоритма, об этом можно почитать в самой статье. Главное, чтобы вы понимали суть.

Наша задача


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

* Сразу хочу сообщить, что вариантов (рабочих и не очень) на самом деле получилось целых 4 штуки, плюс ещё куча интересных и полезных разобранных нюансов, на огромную статью (в моём стиле). Поэтому тут я вкраце опишу некоторые из них :)

Варианты 1 и 2


Самое первое, что пришло мне на ум, это взять список из пяти пунктов и построить выравнивание на старых-добрых float-ах, поэтому я смастерил два варианта (один, два), которые к сожалению оказались не совсем универсальными. Точнее первый из них вообще не прокатил, а второй оказался вполне себе рабочим, но только лишь для фиксированной ширины пунктов.
Кому интересно подробное исследование этих вариантов, милости прошу в саму статью.

Варианты 3


А вот третий вариант уже построен на самом алгоритме text-align: justify и инлайн-блоках, которые и принесли свои плоды, но не совсем. Во-первых, мне пришлось разбавить список лишним, дополнительным элементом, а во-вторых, в IE6-7 обнаружились интересные факты, рыться в которых мне доставило большое удовольствие. В этих браузерех данное решение отказывалось работать вообще. И догадайтесь, кто пришёл мне на помощь. Верно, SelenIT2! Но он пришёл ни один, а с великолепной идеей (которую он нагло спёр у нашего общего коллеги по цеху GreatRash), от которой я был просто в шоке. Как оказалось, пара волшебных свойств CSS3 родом из глубокой древности может превратить это решение в кроссбраузерное и заставить работать text-align: justify в наших старичках IE6-7.

третий вариант

Весь секрет оказался в последней строчке следующего кода:
<ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li class="helper"></li>
</ul>

ul {
        font: 14px Verdana, Geneva, sans-serif;
        text-align: justify;

        /* Обнуляем для родителя*/
        line-height: 0;
        font-size: 1px; /* 1px для Opera */

        /* Лекарство для IE6-7*/
        text-justify: newspaper;
}

Как видно, с помощью text-justify: newspaper; у ul наш вариант становится кроссбраузерным. Это происходит за счёт того, что свойство text-justify: newspaper предназначено для увеличения или уменьшения интервалов между буквами и между словами. MSDN заявляет, что эта вещь «Самая навороченная форма выравнивания для латинского алфавита», а вот в этой статье ещё есть и дополнение, что для арабских текстов это свойство вытягивает и сами буквы.

Варианты 4


Ну, и вариант 4 стал отказом от дополнительной разметки, что повлекло за собой новые проблемы в IE6-7.
image
Оказывается всё дело в том, что text-justify: newspaper лишь даёт возможность растягивать наши буквы (inline-block), но не команду. Проще говоря, он рассказывает строке, как бы он хотел, чтобы она была растянута, а text-align: justify является растягивающей силой. Т.е. text-align: justify отвечает за растяжение строки, а text-justify: newspaper лишь уточняет, как именно это растяжение будет происходить.

В обзоре 3-го варианта я сказал, что SelenIT2 подсказал мне два свойства, одно из которых (text-justify: newspaper) помогло нам в предыдущем варианте, а другое как раз помогло в этом! Причём в этот раз они объединились и уже с двойной силой смогли победить последний вариант.
ul {
        font: 14px Verdana, Geneva, sans-serif;
        text-align: justify;

        /* Обнуляем для родителя*/
        line-height: 0;
        font-size: 1px; /* 1px для Opera */

        /* Лекарство для IE6-7*/
        text-justify: newspaper;
        zoom:1;

        /* Включаем в работу последнюю строку*/
        text-align-last: justify;
}

Встречайте! text-align-last — свойство, которое включает алгоритм text-align: justify в самой последней строке текста, если к ней применён этот самый text-align: justify. Проще говоря, когда мы применяем к тексту обычный text-align: justify, то, видя это, text-align-last указывает первому на то, что он поступает плохо и что ему придётся теперь работать и в последней строчке тоже.

И вот, собственно, результат

Кстати, эти свойства специфицированы, а не какая-нибудь проприетарщина (кроме значения newspaper, которое теперь называется иначе). Так что ни один котенок не пострадает) И хочу подчеркнуть, что баг IE6-7 поборен с помощью CSS3 — кто еще когда такое видел? :)

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

Если краткого обзора кому-то показалось мало, то я рекомендую прочитать вот эту (уже большую) статейку с доскональным разбором полётов. Но, предупреждаю! Статья действительно не маленькая, поэтому перед началом чтения лучше запастись вашими любимыми печеньками с чаем :)
Tags:css
Hubs: Self Promo
+154
11.9k 1300
Comments 87

Popular right now

Front-end software developer
from 150,000 to 250,000 ₽SoftwareONERemote job
JavaScript-разработчик
from 230,000 ₽CORERemote job
Middle Frontend Developer (удаленно)
from 100,000 to 150,000 ₽Студия 15Remote job
Верстальщик
from 1,500 €TR LogicRemote job
Fullstack developer
from 70,000 to 100,000 ₽ScrileНовосибирскRemote job

Top of the last 24 hours