Красивое выравнивание блоков по резиновой сетке

Сегодня, в мой день рождения (26 апреля), я хочу сделать подарок всем верстальщикам и представить вам абсолютно уникальное, новое и самое главное — полезное решение выравнивания блоков по резиновой сетке, которого так все долго ждали и которого ещё нет в сети.

При верстке резиновых страниц часто возникает задача выстроить однотипные блоки (например, товары в каталоге или фотографии в галерее) по сетке, наподобие таблицы, но гибкой, с заранее неизвестным количеством столбцов. Когда-то единственным способом для этого был float, и блоки приходилось прижимать к левому краю. С помощью inline-block эту задачу можно решить проще и гибче, блоки могут иметь разную высоту, и разное вертикальное выравнивание. Но почему-то такие макеты в массе всё равно прижаты к левому краю. Казалось бы, что мешает отцентрировать эту сетку, а то и вовсе растянуть ее по ширине свободного места c помощью text-align: center или justify соответственно?

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

Проблема

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

Проблема очень похожа в обоих случаях, так что выберем любое свойство из двух, например, text-align: center. А так же воспользуемся маркированным списком.

<ul>
	<li>Пункт 1</li>
	<li>Пункт 2</li>
	<li>Пункт 3</li>
	<li>Пункт 4</li>
	<li>Пункт 5</li>
	<li>Пункт 6</li>
	<li>Пункт 7</li>
	<li>Пункт 8</li>
</ul>
ul {
	font: 14px Verdana, Geneva, sans-serif;
	text-align: center;
}

	ul li {
		display : inline-block;
		width : 80px;
		height: 80px;
		margin-bottom: 10px;
		background: #E76D13;
		vertical-align: top;
		text-align: center;
		line-height: normal;

		/* эмуляция inline-block для IE6-7*/
		//display : inline;
		//zoom : 1;
	}

Ничего необычного в коде нет. Обычный список, всё те же старые добрые элементы строчно-блочного (display : inline-block) уровня. Самое пожалуй интересное, что стоит выделить, это text-align: center, благодаря которому и происходит наше горизонтальное выравнивание.
Пока пункты занимают единственную строку, всё выглядит так.

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

Вроде бы тоже неплохо, всё происходит так, как и должно происходить. Последняя строка так же, как и предыдущие — выравнивается по середине. Но, именно это выравнивание и создаёт нам проблему. Блоки находятся по середине, создавая по бокам много ненужного и пустого пространства. Если бы, например, в последней строке остался всего один блок, то этого бы пространства стало ещё больше, а сам блок болтался бы в середине, как изгой на пустыре.

А теперь, давайте взглянем, чтобы мы хотели получить.

Как видно из рисунка, два элемента в последней строке прижались к левому краю, не смотря на то, что строка по ширине явно больше, чем общая ширина её блоков. Это видно по правому, свободному пространству, которое составляет две трети наших элементов. Именно такое поведение блоков нам и нужно получить в итоге. Т.е. по сути сделать так, чтобы выравнивание элементов было красивым, строящимся ровно по сетке (даже по резиновой), не взирая на своё количество и лишнее пустое пространство в последней строке. Говоря другими словами, нам нужно каким либо образом повлиять на поведение последней строки, заставив её подчиняться нашим правилам.

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

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

text-align: center

Начнём пожалуй с text-align: center. В нем можно выделить три основных этапа.

Первый этап
В начале берётся строка. Высчитывается общая ширина слов или неразрывных блоков (inline-block, img, и т.д) в строке. Причём если между этими блоками есть фактические пробелы или же отступы, которые сделаны с помощью таких средств, как word-spacing и прочих, то эти расстояния так же добавляются к общей сумме ширины блоков.

Второй этап
На этом этапе всё ещё проще. Вычисляется оставшееся ширина строки, т.е. всё свободное пространство, которое не вошло в сумму общей ширины слов с их межсловным расстоянием.

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

Перед нами рисунок, на котором изображён контейнер, с двумя строками, ширина которых составляет 500px.
Так же мы можем видеть, что сумма всех блоков в первой строке с их интервалами равна 370px. Значит на третьем этапе наш алгоритм вычел из первого второе (500-370), что дало результат 130. Далее, как я уже говорил, поделил эту сумму ровно на два раза (130/2) и отодвинул самый первый блок вправо, на полученный результат (65px). Таким образом наши блоки оказались точно по середине, с отступы по бокам стали абсолютно одинаковыми. Если бы в первой строке не хватило места, то самый крайний справа блок перешёл бы на второю строку и алгоритм снова включился бы в дело.

Тоже самое касается и второй строки. В ней алгоритм работает точно так же, мало того, можно увидеть, что боковые отступы в ней составляют дробное число (132.5px), так как text-align: center делит общую ширину блоков с их интервалами ровно на 2, как я и говорил.

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

text-align: justify

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

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

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

Решение

Сразу забегу вперёд и скажу, что решение для обоих случаев абсолютно идентично, поэтому нет смысла разбирать каждое из них в отдельности. Так что давайте поразмыслим, что у нас есть на данный момент.
Значит, по сути, у нас есть два свойства text-align: justify и center, каждый из которых выравнивает строки по собственному алгоритму. А так же мы уже понимаем, что text-align: center работает с последней строкой, а вот text-align: justify — нет. Но зато мы точно знаем, что если строка, за которой идёт следующая (допустим последняя) будет полностью заполнена, то эти свойства будут выравнивать нашу сетку по нашим правилам. И даже при резиновой ширине контейнера такие заполненные строки будут вести себя так, как нам хотелось бы.

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

Итак, для заполнения последней строки, мы будем использовать псевдоэлемент, сгенерированный при помощи :after. Это хороший вариант, так как он поможет решить нам нашу задачу и избавит от лишнего мусора в разметке. По умолчанию псевдоэлементы генерируют строчный блок, а значит именно то, что нам и нужно. Так как inline-block будет представлять из себя одну большую, неразрывную букву и не сможет разбиться на несколько "кирпичей", что не приведёт ни к чему путному. Ну, а block сразу же займёт отдельную строку, и так же, как и inline-block — не принесёт результатов. При этих значениях наша ситуация будет выглядеть примерно так.

ul:after {
	content: 'display: block, мало контента';
	display: block;
	background: #E76D13;
}

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

Из всего вышесказанного можно понять одно, что в нашей ситуации нам может помочь элемент, именно строчного (inline) уровня, т.е. обычный display : inline + строка текста, с пробелами между слов.

ul:after {
	content: 'Обычный строковый элемент, обычный строковый элемент, обычный строковый элемент';
	background: #E76D13;
}

Да, очень похоже. Из скриншота ясно, строчный блок, мало того, что смог повлиять на последнюю строку, так ещё и перенёсся на следующую не полностью, оставив на предыдущей строчке неразрывное слово. По этому слову видно, что по своей ширине оно немного не дотягивает до ширины блоков (100px), а если бы дотягивало, то, возможно, у нас и вышло бы что-то путное.

В общем поэкспериментировав какое-то время с вышесказаннным, на свет родилось следующее решение.

ul {
	font: 14px Verdana, Geneva, sans-serif;
	text-align: center;
	margin: 0px 0 10px;
}
	ul:after {
		content: ' i i i i i i i i ';
		word-spacing: 97px;
		padding-left: 97px;
		/* visibility: hidden; Скрыл это свойство, ради демонстрации процесса*/
	}
		ul li {

			display : inline-block;
			width : 100px;
			height: 100px;
			margin: 0px 0 20px;
			background: #E76D13;
			vertical-align: top;
			text-align: center;

			/* эмуляция inline-block для IE6-7*/
			//display : inline;
			//zoom : 1;
		}

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

Значит у нас есть строка "i i i i i i i i"  , состоящая из букв и пробелов, но это не простые буковки и пробелы, как может показаться на первый взгляд. Во-первых сама буква i выбрана не случайно. Дело в том, что буква i сама по себе узкая, за счёт чего ей легко управлять и подгонять нужную ширину. Во-вторых сами пробелы состоят не только из символа пробела, но и из word-spacing, т.е. его значение плюсуется к пробелу, что в сумме даёт нужную нам ширину. Да, и конечно же, нужно учитывать, что связка "пробел + word-spacing" работает только тогда, когда в конце неё идёт другой символ, отличный от пробельного. Так как пробелы имеют свойство "схлопывания", то буквы i, идущие после word-spacing не дают им этого сделать.

Так что, по сути, мы имеем неразрывные псевдоблоки, в виде "буквы + padding-left" вначале псевдоэлемента, а далее в виде связки "пробел + word-spacing + буква", и так до конца строки. Ну, а на следующей строчке всё повторяется заново, только первый псевдоблок состоит теперь из одной буквы. Но эта строка нас уже не волнует, нас интересуют только те "добавочные блоки", которые дополняют последнюю строку с нормальными блоками в сетке.
Кстати, букв должно хватить, чтобы гарантировано заполнить последнюю строку до конца в худшем случае. Т.е. их число должно быть равно максимальному кол-ву блоков в строке.
Да, и, конечно же, с text-align: justify этот метод работает точно так же.

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

Во-вторых, из-за создания дополнительных элементов снизу образовывается неприятный отступ, который происходит за счёт его размера шрифта и межстрочного интервала. Лекарство в виде обнуления шрифта + межстрочного интервала у родителя и восстановлением их в нормальное состояние у потомков — не приносит результата, так как нужная нам строка в псевдоэлементе становится невидимая, и наша сетка перестаёт её чувствовать и поддаваться дрессировке.
Но есть всё же "почти" выход из ситуации, это нижний отрицательный margin, который может подтянуть часть своего "хвоста", позволяя следующим за ним элементам налезать на него. Подробнее об этом можно почитать тут. Я сказал "почти", потому что этот способ выручает отчасти, я бы сказал, на половину, может чуть больше. Так как в момент создания, уже двух-строчного хвоста, из букв, подтянуть обе строки, уже не представляется возможности.

Во-третьих, чтобы заставить этот метод работать в IE6-7, нам потребуется заменить наш псевдоэлемент дополнительным блоком-помощником, который будет вставлен в конце списка. Плюс к этому придётся воспользоваться такими средствами, как text-justify, text-align-last (их поведение я уже описывал в этой статье), восстановлением свойства zoom в начальное состояние, у дополнительного блока и прочими "радостями", благодаря которым, в этих браузерах наш способ будет работать так же. В конце статьи я обязательно приведу разные варианты этой задачи, чтобы вы могли выбрать нужный.

Резюме

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

Да, и конечно же, хочется выразить огромную благодарность Илье Стрельцыну (@SelenIT2) за его идеи и невероятную помощь в материалах. Без него бы этой статьи не было.

Все решения воедино

P.S. Это тоже может быть интересно:

59 Комментарии

  1. Анна

    А как требовалось в свое время вот так вот выровнять картинки… И как я мучилась.
    Очень понравился метод. Нечто подобное (аналогичный псевдоблок) я уже использовала, но не в таком сочетании. Даже у себя на сайте выложила.

    1. psywalker (Автор записи)

      Надеюсь теперь ваше мучение отпадёт :)

  2. Tosha

    Скажите пожалуйста, а разве простой float блоков вас не устроил бы?
    вам же надо располагать элементы друг под другом,
    ну или с тем же display: inline-block; но не выравнивая по центру, а как обычно по левому краю?

    1. psywalker (Автор записи)

      Простой float не получится выравнивать по ширине, например. Именно по этой причине я использовал inline-block.

    2. SelenIT

      Весь фокус именно в центрировании всего блока с одновременным сохранением ритма сетки в последней строке. Ни равнение по левому краю, ни тем более флоаты такому не обучены.

      1. they can

        http://foto.volg-gsm.ru/sections/1/

        вот здесь обучены и умеют.

        1. psywalker (Автор записи)

          Там сделано на float, и попробуй добиться такого же эффекта на них.
          http://css-live.ru/Primer/beautiful-viravnivanie/main2.html

          1. they can

            Мы немного не понимаем друг друга. Мой ответ был адресован SelenIT. В том смысле, что float (на котором основано решение в приведенной ссылке) умеет «выравнивать влево» и «сохранять ритм сетки в последней строке». Поправьте меня если я неправильно понял контекст фразы.

        2. SelenIT

          В упор не наблюдаю по ссылке центрирования :). Да и резиновости тоже. О чем, между прочем, сказано в начале статьи:

          Когда-то единственным способом для этого был float, и блоки приходилось прижимать к левому краю.

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

          1. they can

            Я не понимаю Вас. Как можно центрировать и прижимать к левому краю одновременно?! Может быть стоит автору чуть поправить в этом месте текст?

            1. SelenIT

              Центрировать всю колонку. А внутри нее прижимать элементы последней (неполной) строки к левому краю.

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

              Ни того, ни другого эффекта float-ы не дают в силу своей природы.

              1. they can

                Ах да! Вы правы. Спасибо за разъяснение

  3. troll

    Теоретически отступ снизу убирается так: для ul ставится line-height: 0, а на li восстанавливается в normal.

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

    http://jsfiddle.net/4nAyZ/

    1. SelenIT

      Отличная мысль!

      Полтора года назад, когда я пытался применить подобный финт в другой задаче, Хром и Сафари отказывались уменьшать фактический line-height меньше высоты строчных букв, поэтому я это направление упустил… А в актуальных, похоже, действительно работает — получается просто и изящно. Спасибо!

  4. Seva

    Спасибо за статью, с прошедшим теьбя!))

  5. SurPaul

    спасибо, вспомнил SkyDrive от Microsoft, там тоже так сделали… афтор, с прошедшим)))

  6. Юрий

    A как насчет размещаемого внутри контента? Можно ли там внутри размещать плавающие блоки?
    Например такой код:

    figure
    img style: float:left;
    figcaption style: float:right;
    dl
    dt
    dd
    a, etc..
    /figcaption
    /figure

    У меня при таком раскладе в IE все нормально а в FF получились отступы большими по горизонтали.

    1. SelenIT

      Должно быть всё нормально, внутри инлайн-блоков может быть любое блочное содержимое. Можно увидеть проблему на примере?

      1. Юрий

        Я закинул страничку сюда: http://petuhovo-foto.narod.ru/tmp/exemple.html
        В FF первый рад имеет большие промежутки, остальные наоборот отсекают часть текста соседей, в Опере и Гугл примерно так же. В Опере еще блоки как бы собираются пирамидой в левом верхнем углу.

        1. SelenIT

          У вас почему-то только в первом ряду между </li> <li> есть пробелы (переносы строк), начиная с 4-го элемента соседние </li><li> идут вплотную. Чтобы инлайн-блоки раздвигались с помощью text-align: justify, пробелы между тегами нужны (в противоположность другой задаче, где они только мешают).

          1. Юрий

            По моему это не очень хорошо когда представление страницы зависит не от CSS а от форматирования HTML:/
            Я тут недавно наткнулся на фреймворк Semantic GS.
            Он использует LESS. Его сетка весит около 2х Кб., но на её основе можно сверстать шаблон любой сложности.
            Вот для примера решение подобной задачи этим фреймворком: http://semantic.gs/examples/nested/nested.html
            И к тому же если взглянуть на исходный код страницы, там не обнаружится изобилия всяких классов типа «column_6 column_last», чем грешат многие фреймворки :)

            1. SelenIT

              Возможности CSS, увы, небезграничны. Работа justify — растягивать пробелы, если их нет — что поделаешь… (хотя CSS3 решает и эту проблему через text-justify: distribute, но работает это пока лишь в IE, в виде text-justify: newspaper).

              Пример по ссылке решает совсем другую задачу — там кол-во колонок фиксировано. К тому же оформление генерируется и навешивается джаваскриптом, и есть обоснованное мнение, что изобилие классов — существенно меньшее зло :)

              1. Юрий

                Насколько я знаю, есть возможность для less сгенерировать css на сервере.
                Или ещё как вариант есть программы-компиляторы, например SimpLess: http://wearekiss.com/simpless

                1. SelenIT

                  Возможность, конечно, есть. Но есть опасения, что после компиляции CSS потеряет изрядную долю изящества.

  7. TimuR

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

  8. Kotomorda

    Opera 11.64 несколько по-своему понимает данную задачу: http://s019.radikal.ru/i642/1205/3c/4facb8b7ed0e.jpg

    1. psywalker (Автор записи)

      Да, есть такое дело, но здесь уже ничего не попишешь, если только Норвежцы не исправят это в новой версии.

  9. set

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

    1. SelenIT

      Если выравнивание небольшого кол-ва блоков по центру ожидаемо — используйте простой text-align:center без добавок :)

      Прием предназачен для случая, когда ожидаемым является заполнение блоками всего доступного пространства, с единообразным распределением лишних промежутков.

      1. set

        хм, неожиданный ответ… дело в том, что вёрстка делается для сайта целяком, а не для конкретного сферического блока в вакууме, следовательно, может получиться так, что в одной категории товаров много, а в другой — мало, да и при разбивке на страницы может получиться так, что на последней странице окажетсявсего 1-2 товара. К тому же — сайт резиновый и невозможно знать, с каким разрешением пользователь будет просматривать его, значит, даже 10 товаров на странице могут оказаться всего в одной строке, да и то не полной.

        1. SelenIT

          При предлагаемой схеме эти 1-2 товара будут в точности на том же месте, где первые 1-2 товара на всех других страницах, без скачков и перескоков.

          Резиновый дизайн хорош без крайностей, да и реальные разрешения больше 2 — 2.5 тыс. CSS-пикселей — экзотика. Так что есть смысл ориентироваться на разумный предел кол-ва блоков в строке (хотя бы с точки зрения удобства чтения). Можно "допилить" CMS, чтобы она добавляла класс, включающий резиновую сетку, только в случае, если блоков больше этого числа. Или использовать JS.

          Чисто CSS-ного решения сходу на ум не приходит, но я еще над ним подумаю. Хотя, по-моему, задача слегка притянута…

          1. set

            При предлагаемой схеме эти 1-2 товара будут в точности на том же месте, где первые 1-2 товара на всех других страницах, без скачков и перескоков, как при обычном центрировании.

            вам не кажется, что в этом предложении скрыто противоречие? :)товары будут в точности на том же месте, где первые 1-2 товара на всех других страницах — согласен, но при этом они не отцентрованы будут. будет отцентрован родитеслький блок, но товары в нём будут слева, а не по центру.
            касательно движка, который классы дописывать будет — ну так а от чего отталкиватсья при резине? движок же знать не знает, при каком разрешении юзер будет просматривать страницу в итоге. открыть может в одном разрешении, а потом развернуть, скажем, браузер на всю ширину экрана. 
            если же говорить о яваскрипте, то тогда отпадает необходимость в самом способе — достаточно определять яваскриптом ширину некоего враппера, делить её на ширину отдельного товара, округлять в меньшую сторону до целого числа и умножать на ширину товара, после чего просто дописать эту ширину родительскому блоку. и проводить эту процедуру после загрузки документа и при ресайзе окна. я просто хотел найти вариант бзе скрипта. вот, _почти_ нашёл :)

            1. SelenIT

              будет отцентрован родитеслький блок, но товары в нём будут слева, а не по центру.

              Вообще-то именно для этого метод и придумывался :)

              1. set

                знаете, вы очень странные комментарии оставляете, как для человека, имеющего непосредственное отношение к статье… вы настойчиво делаете вид, что не понимаете, о чём я говорю! неужели самолюбие не позволяет вам признать, что вы не знаете решения? мне, к примеру, позволяет, несмотря на приличный опыт. простите, но я ожидал от вас немного другой рекции — попытки помочь, подсказать или посетовать на то, что не получается найти решения, но уж явно не того, что вы сейчас пишете…  спасибо за вашу надменность, она очень помогла!

                1. SelenIT

                  Извините за то, что вам показалось надменностью. Я понял задачу так, чтобы, пока блоки заведомо встают в одну строку, работало обычное центрирование, а при переполнении этой строки автоматически включалась сетка из статьи. И я сразу признался, что не знаю решения, потому что метод разрабатывался для другой задачи.

                  1. set

                    жаль… прийдётся выходить из ситуации с помощью яваскрипта :( а так хотелось красивого решения :(

  10. Михаил

    Помоему говнометод. Ради чего это все? Добавил див лишний и готово дело. Нет.. Надо какие-то  iiii.

    1. psywalker (Автор записи)

      А откуда такая уверенность, что этот div понадобится вообще? Средствами CSS это проверить невозможно, а вот решить такую задачу на CSS оказывается есть возможность;)

    2. SelenIT

      Один лишний див? Можно примерчик?

  11. Дмитрий

    Opera
    Версия:12.11
    Сборка:1661
    Принудительно переносит последний элемент, когда сумарная ширина li не превышает ширины родителя принскрин:  http://clip2net.com/s/2C6NX

    1. SelenIT

      К сожалению, есть такая проблема (упомянута в конце статьи, как первый из минусов метода). Решение пока не найдено. Может быть, у вас есть какие-нибудь идеи, как это побороть?

  12. Владислав

    Рассматривался ли вариант использования элемента WORD JOINER вместо буквы i? На первый взгляд он позволяет избежать зависимости от размера шрифта.

    1. SelenIT

      Отличная идея! Попробуем поэкспериментировать, как только будет время, если покажете пример раньше — заранее большое спасибо! :)

      1. Владислав

        Такой вариант не работает в опере (mac), IE еще не тестировал. Также требует дополнительного элемента (хотя я мог неправильно задать content). Из всех zero-width элементов только этот не воспринимается браузерами как пробел (ну, кроме оперы).
        Демо на jsFiddle

        1. SelenIT

          Смог побороть последнюю Оперу (Win 7) с помощью такого финта ушами. К сожалению, сломались вебкиты (у меня ни Хром, ни Сафари вообще не захотели отображать u-2060 'Word Joiner', нарисовали квадратики как для незнакомого символа и этим поломали всю сетку). И с content почему-то тоже ничего не вышло.

          Вот бы теперь соединить рабочие варианты для Оперы и для вебкитов… :)

        2. SelenIT

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

          1. Владислав

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

            1. SelenIT

              Вероятно, от шрифта по умолчанию зависит… хотя всё равно странно. Но у меня вебкиты упорно не отображают символ &8288; (точнее, как раз отображают — квадратиком:(.

              Самое занятное, что без этого символа всё прекрасно и в Вебкитах, и в Опере, но в этом случае выделывается уже Firefox. И никак не могу понять причину разного поведения элемента и псевдоэлемента…

              1. Владислав

                Получилось перенести .helper в :after (кажется), просто скопировав em space и word-joiner (без всяких кодов). Но наверняка тут кроется куча возможных проблем, о которых я не знаю. 
                 
                Демо

              2. Владислав

                Кстати, в итоге вот что получилось
                 

  13. Александр

    Это просто гениально!!!! Спасибо огромное!! Я бы сам точно не додумался!!

  14. Zverushka

    Ребята, я это сделала не специально, можно сказать случайно. Но все работает без всяких приблуд. Посмотрите, что скажете?

    http://jsfiddle.net/4nAyZ/82/

    1. SelenIT

      Justify не работает, к сожалению. Потому что не пробелов, которые он мог бы растянуть. Получается обычное выравнивание по левому краю, как и с флоатами. Если условия задачи это позволяют, то всё ОК, иначе, видимо, без приблуд не обойтись.

  15. Кирилл

    А как побороть вот такой дефект?

  16. Александр

    Случайно сюда зашел, немножко другая проблема была… но твой пост очень-очень выручил! Спасибо тебе!

  17. Александр

    Привет! Возможно, вопрос не совсем по теме, но тоже связан с отступами.
    Настраиваю адаптивную галерею на странице http://sakulin.com/portfolio/ и никак не могу победить один дефект.
    При загрузке страницы возникает ошибка: галерея начинает вылазить за границы контента. Причем ширина страницы рассчитывается правильно, это видно в инспекторе. Если потянуть за границы окна, то все мгновенно становится на свои места, и галерея выравнивается.
    Эта проблема не наблюдается на маленькой ширине экрана (когда все изображения выстраиваются в одну колонку). Поэтому я предполагаю, что проблема именно в горизонтальных отступах между изображениями.
    Ширина блоков с изображениями указана в процентах, а отступы с помощью:

    .gutter-size{width:0.5%;display:block}

    Подскажите, пожалуйста, как это победить?
    P.S. Странно, что на маке и в http://quirktools.com/screenfly/ (просмотр на разных разрешениях экрана) все в порядке, галерея сразу загружается правильно.

  18. Alexander

    Спасибо, метод работает более-менее, но идеально точного позиционирования при изменяемой ширине окна добиться не удалось даже используя моноширный шрифт с заданным размером для псевдо-блока.

    Всё-таки это костыль. Пробовал решить эту же задачу с примененеием flexbox, но похоже здесь он бесполезен. Может быть у кого-то всё же получилось сделать то же самое посовременнее?

    1. SelenIT

      Боюсь, что до массового прихода Grid Layout простого решения (надежнее дедовского метода с кучей пустых блоков-распорок, которые здесь пытается заменить собой псевдоэлемент) найти вряд ли удастся. Зато с гридами задача станет элементарной. Осталось всего-то потерпеть до весны!

      1. Alexander

        Спасибо за наводку про дедовский способ, он мне больше подошёл :)

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.