4 февраля 2012 в 02:17

«Загадочные отступы» между инлайн-элементами

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

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


Для начала мне хотелось бы пояснить, что же такое inline-block и почему все решения мы будем обсуждать именно с ним.

inline-block


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

Строчное поведение inline-block позволяет ему оставаться в одной строке с другими строчными элементами, например <span>-ом или попусту сливаться с обычными буквами, т.е. вести себя, как текст в строке. Ну, а благодаря своим блочным способностям, inline-block-у можно смело задавать любые свойства, которые присуще блочным элементам… ширину, высоту, верхний и нижний margin, например, уже будет действовать, как у блоков.
Ну и т.д., в общем, эдакий "блок-строка"

image

Живой пример

Как видно из примера, inline-block чувствует высоту и ширину, которую мы ему прописали. Так же можно заметить одну интересную штуку, наш подопечный выровнялся по вертикали, выровнялся так, как и должны выравниваться большинство инлайн-элементов в html, т.е. по базовой линии (baseline), т.е. выравнивается наш блок относительно своего текста, который в нём находится. Добавляем текста в блок и смотрим результат.

image

Блок выровнялся по базовой линии. Чего и следовало ожидать.
Сразу же приведу несколько разных примеров, поведения inline-block с разным вертикальным выравниванием.

Разное выравнивание

Тут я продемонстрировал три разных выравнивания, но на самом деле их намного больше, если интересно, то вот здесь описаны все возможные варианты. В данной статье нет смысла всех их описывать. Просто учитывайте это, при работе с inline-block.

inline-block — как буква


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

Почему в статье я использую именно inline-block?


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

Загадочные отступы


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

<ul>
	<li>Пункт 1</li>
	<li>Пункт 2</li>
	<li>Пункт 3</li>
	<li>Пункт 4</li>
	<li>Пункт 5</li>
</ul>

ul {
	font: 14px Verdana,sans-serif;
}
	ul li {
		display : inline-block ;
		width : 100px;
		border : 1px solid #E76D13;

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

	 }


image

На картинке отчётливо видны пробелы между пунктами меню. Откуда же они берутся? Причина кроется в том, что, как мы уже выяснили, inline-block ведет себя, как обычная буква, а значит так же, как и простой текст — имеет пробелы между словами. Эти пробелы можно отчётливо наблюдать в разных веб-инспекторах, например таких как "IE WebDeveloper" для Internet Explorer.
В итоге мы видим ту самую "неприятность", из-за которой мы все тут и собрались.

image

Как мы видим, браузер создаёт пустой текстовый узел, который, по сути, может являться переводом строки, пробелом или, например, табом. Все и эти перечисленные вещи превращаются в один единственный пробел и описывается следующей сущностью: &#x0020;. Так же следует учитывать, что, так как пробел — это обычный символ, то соответственно и изменяться этот самый символ будет в зависимости от размера или семейства шрифта, т.е, по сути, вести себя точно также, как и обычная буква в строке. Всё это обязательно следует учитывать при вёрстке.

Наша задача


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

Материал для работы


Давайте поразмыслим, что же нам сможет помочь для решения этой задачи.
  • 1. margin-left (отрицательный) — свойство, с помощью которого можно сдвинуть пункты влево, как бы на друг друга, "избавившись" так сказать от ненавистного пробела между них.
  • 2. font-size — свойство, задающее размер шрифта, с помощью которого нашему пробелу (символу) можно выставить размер шрифта, равным нулю, и тем самым сделать его настолько маленьким, что его попусту не будет видно.
  • 3. letter-spacing — свойство, определяющее интервал между символами. По умолчанию (normal) задаёт обычный интервал, исходя из размера и типа шрифта.
  • 4. word-spacing — свойство, определяющее интервал между словами. По умолчанию так же, как и letter-spacing, задаёт его в зависимости от размера и типа шрифта.
  • 5. Прижать элементы друг к другу, т.е. вплотную, тег к тегу, и таким образом убрать межссловный интервал.
  • 6. Поставить комментарии между элементами, и тем самым убрав между ними отступы.
  • 7. Самое, на мой взгляд, интересное решение из всех… оставлю его пожалуй на закуску… интрига...

Плюс ко всему сделаем тестовый элемент  <div>Ширина = 510px</div>, который будет нашей вспомогательной линейкой. Ширина наших пунктов в сумме составляет 510px. Это боковые границы + их ширина + кол-во самих пунктов ((1+100+1)*5) = 510.
Вроде ничего не забыли, поэтому переходим к рассмотрению всех вышеперечисленных вариантов.

Вариант 1 — margin-left


Первым у нас на очереди выступает левый отрицательный margin. Посмотрим, как он сможет помочь нам.
Код CSS для наглядности:
ul {
	font: 14px Verdana,sans-serif;
}
	ul li {
		display : inline-block;
		width : 100px;
		border : 1px solid #E76D13;
		margin-left: -.36em;

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

		/* margin-left отдельно для  IE6-7 */
		//margin-left: 0;
	}


Из кода видно, что для общего списка я выставил шрифт Verdana и размер шрифта в 14px (в наших примерах будет отталкиваться от этих значений). Ну и, конечно же, левый отрицательный margin, равный -.36em. Как вы могли заметить, для нашей цели я выбрал именно масштабируемую единицу длины (em), потому что, как мы уже знаем, наш пробел пляшет от размера шрифта, а значит, может масштабироваться в зависимости от него. Долго повозившись со значениями, я определил, что -.36em) подходит для нашего шрифта лучше всего (для иного придётся подбирать другие значения), так что оставим, пожалуй, именно этот масштаб. Посмотрим на результат:

image

Как мы можем наблюдать из скриншота, наши пункты уехали за левую границу, что в принципе и очевидно, ведь мы же по сути подвинули все пункты влево, а значит, и первый пункт так же уехал в левую сторону. Для решения этого "недоразумения", мы можем обнулить margin-left именно у первого пункта меню, добавив в наш код следующую запись ul li:first-child { margin-left: 0;}.
*Стоит заметить, что для IE6-7 мы вообще обнулили margin-left, а почему… мы узнаем чуть позже.
А между делом смотрим результат:

image

Да, действительно, на данный момент во всех браузерах всё здорово и смотрится одинаково. Хм… неужели мы добились своей цели? Давайте проверим это, сделав размер шрифта, к примеру, в два раза больше.

ul {
	font: 28px Verdana,sans-serif;
}
	ul li {
		display : inline-block;
		width : 100px;
		border : 1px solid #E76D13;
		margin-left: -.36em;

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

		/* margin-left отдельно для  IE6-7 */
		//margin-left: 0;
	}

	ul li:first-child { margin-left: 0;}.


image

Как можно видеть, мы достигли своей цели, но это до тех пор, пока мы не поменяли шрифт, например, на Arial (предварительно подогнав под него левый, отрицательный margin)

image

image

Выставив фон нашему списку, мы можем заметить, что теперь результаты немного разнятся в браузерах Chrome, Opera 11.53, IE6-8 и Firefox 8, IE 9. В первых всё осталось на своих местах, а вот в последних можно заметить небольшой отступ справа, что говорит о том, что всё-таки есть риск получить немного не ту картину, которую мы задумывали изначально. Как вариант, конечно же, можно подогнать спец. значения для Firefox 8 и IE 9 отдельно, но, опять же, это не очень хорошее решение, так как во-первых, это по сути костыль, а во-вторых, не даёт полной универсальности, ведь никогда не знаешь, при каких размерах и как, поведут себя остальные браузеры.

В общем, я, лично, сделал вывод, что это вполне себе нормальный и жизнеспособный вариант, в фиксированной ситуации можно подогнать размеры и будет всё в порядке. Ряд минусов конечно же тоже есть, в виде обнуления margin-left у первого пункта + подгонка значений для разных браузеров, ну и… конечно же есть доля риска, из-за которой могут быть, хоть и не большие, но какие-то отличия с отступами, при разных шрифтах и их размерах.

Результат с margin-left

Вариант 2 — font-size


Как вы уже знаете, font-size влияет на размер шрифта элемента, делая его больше или меньше, в зависимости от своего значения. Пробел — это символ, который исходит от этого самого размера шрифта, а значит, с помощью font-size мы можем попробовать воздействовать на него, например, выставив его значение в ноль и тем самым, возможно полностью "скрыть" наш ненавистный пробел. Давайте проверим это на деле.

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

	/* Выставляем родителю значение в ноль */
	font-size: 0;
}
	ul li {
		display : inline-block;
		width : 100px;
		border : 1px solid #E76D13;

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


image

Что произошло с символами? Куда они все пропали? На самом деле всё просто. font-size наследуемое свойство, а значит, выставив родителю (в нашем случае UL) какое либо значение, отличное от значения по умолчанию, мы должны возвратить font-size в прежнее состояние, у потомков (в нашем случае у LI).

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

	/* Выставляем родителю значение в ноль */
	font-size: 0;
}
	ul li {
		display : inline-block;
		width : 100px;
		border : 1px solid #E76D13;

		/* Возвращаем в нормальное состояние у потомков */
		font-size: 14px;

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


image

Отлично! Теперь всё работает! Но везде ли? Проверяем… упс… к сожалению почти...

image

image

Как видно из скриншотов, Safari подвёл нас, напрочь отказавшись обнулять наш межсловный символ :(. Почему же так произошло? Не найдя ответа на этот вопрос, я рискнул предположить, что всё-таки это ни что иное, как самый настоящий баг браузера Safari и поэтому, нам нужно, либо искать вменяемое лекарство от этого бага, либо отказываться от этого способа, полностью. Исключать этот способ из списка не очень хочется, потому что, во-первых, этот вариант не работает лишь в Safari, а во-вторых, моя интуиция мне подсказывала, что решение всё же имеется. В итоге спортивный интерес взял вверх и решение всё таки нашлось! Да, и при чём оно оказалось для меня приятной неожиданностью. Ответ кроется в свойстве display: table, которое вешается на контейнер с пунктами (в нашем случае UL). Проверим.

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

	/* Выставляем родителю значение в ноль */
	font-size: 0;

	/* Лекарство отдельно для Safari */
	display: table;
}
	ul li {
		display : inline-block;
		width : 100px;
		border : 1px solid #E76D13;

		/* Возвращаем в нормальное состояние у потомков */
		font-size: 14px;

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


А вот и скриншот из Safari:

image

Супер! Сработало! Но как же это так? Возможно, при display:table движок воспринимает строку блоков внутри как "что-то вроде table-cell", т.е. ячеек таблицы, в каких-то FF до 3.6, если я ничего не путаю, был похожий баг.

Чем это может нам грозить?

Есть пару мелких недостатков, о которых следовало бы знать.
1. Во всех браузерах, кроме Firefox, точкой отсчёта позиционированных элементов являются ближайший предок с relative, т.е. это может быть та же ячейка (TD). Но у нас тут не TD, а LI, так что в этом плане проблем у нас точно не будет. Но проблемы будут, если мы захотим позиционировать сами LI, внутри UL, а так как UL у нас — это, по сути, таблица, то Firefox откажется позиционировать пункты относительно её. Но тут не стоит беспокоиться, так как в этом случае на помощь к нам придёт обычная обёртка (например div) для элемента UL.
* Кстати, спустя несколько лет, я всё таки нашёл решение этой проблемы.
2. Второй нюанс — ширина. display:table по умолчанию не растягивается на доступное пространство, так что может понадобиться еще выставление ширины контейнеру (а при наличии бордеров/паддингов — box-sizing: border-box c нужными префиксами вдобавок).
Это что касалось самого display:table, а что же сам font-size? У него есть минусы? Да, есть, пожалуй, один неприятный недостаток. Из-за нулевого значения font-size у родителя, мы не можем применять масштабируемые единицы длины к потомкам, т.к. они отталкиваются от наследуемого размера шрифта и соответственно от нуля в нашем случае. Ну и плюс ко всему, это то, что всегда надо быть начеку и смотреть, чтобы у потомков был переназначен размер шрифта.
Ну а так в целом способ, вполне себе рабочий, если не считать нюансы. Так что смотрим пример в действии и идём дальше.

Решение с font-size

Вариант 3 — letter-spacing


Третьим номером у нас идёт letter-spacing. Чуть ранее мы выяснили, что это свойство влияет на интервал между символами, а так как наш inline-block по сути и есть один, большой символ, то letter-spacing всё таки должен помочь в решении нашей задачи. Как и в прошлый раз, я повозился с масштабом и выяснил, что -.36em будет как раз то, что нужно для Verdana.
* Да, и ещё стоит учесть, что letter-spacing, как и font-size, наследуемое свойство, поэтому нам придётся проделывать ту же операцию с обнулением потомков, что и во втором варианте.

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

	/* Выставляем родителю значение -.36em */
	letter-spacing : -.36em;
}
	ul li {
		display : inline-block;
		width : 100px;
		border : 1px solid #E76D13;

		/* Возвращаем в нормальное состояние у потомков */
		letter-spacing: normal;

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


image

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

image

image

Во всех браузерах, кроме Opera, мы можем наблюдать вполне себе отличную картину, но вот в самой Opera к сожалению всё наоборот. Как оказалось, Норвежцы считают, что letter-spacing может влиять на всё, кроме пробела. Видимо из-за того, что символ пробела означает конец слова, а значит и letter-spacing заканчивает на этом свою работу, так как предназначен для сдвижки/раздвижки букв, именно внутри слова (в т.ч. для кернинга вручную). И тут не имеет значения, что inline-block тоже по сути буква, после неё есть пробел, а значит в любом случае, слово по факту, закончилось.
Считать ли это багом Opera? Ну не знаю, ситуация двоякая, и те и другие по своему правы, так что предлагаю оставить это на совести самой Opera, а самим отправиться на поиски решения этой проблемы.

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

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

	/* Выставляем родителю значение -.36em */
	letter-spacing : -.36em;
	font-size : 0;
}
	ul li {
		display : inline-block;
		width : 100px;
		border : 1px solid #E76D13;

		/* Возвращаем в нормальное состояние у потомков */
		letter-spacing: normal;
		font-size : 14px;

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


Да, вот теперь всё отлично, font-size действительно смог нам помочь. Из этого я сделал вывод, что по сути можно пользоваться обоими вариантами в равной степени: font-size + display-table или letter-spacing + font-size. Т.е. как в первом, так и во втором случае нам требуются вспомогательные инструменты в виде дополнительных свойств.

Upd: Кстати, пока писал статью, обнаружил странный баг в Safari. Когда выставляешь родителю связку font-size: 0 и letter-spacing в любое значение em, например letter-spacing: -.36em, то в Safari всё сразу же рушится((. Причину этого странного поведения Safari мне так и не удалось выявить. Буду рад услышать ответ на этот вопрос в комментариях. Решением с моей стороны является выставление значений letter-spacing, например в пиксели.

Результат с letter-spacing

Вариант 4 — word-spacing


Сразу же хочется отметить, что word-spacing и letter-spacing похожи друг на друга и отличаются только лишь тем, что первый работает с расстоянием между символами, а второй — между словами. При этом word-spacing так же имеет свои недостатки, но в отличие от letter-spacing, с недостатками word-spacing можно бороться, что не может не радовать.
* Также стоит отметить, что word-spacing тоже наследуемое свойство, поэтому в целом код будет напоминать код с letter-spacing. Так что подбираем значение и в путь.

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

	/* Выставляем родителю значение -.36em */
	word-spacing: -.36em;
}
	ul li {
		display : inline-block;
		width : 100px;
		border : 1px solid #E76D13;

		/* Возвращаем в нормальное состояние у потомков */
		word-spacing: normal;

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


По коду вроде всё уже ясно, переходим к скриншотам:

image

image

Ну и конечно же снова не обошлось без происшествий. Но теперь уже оба webkit-a (Chrome и Safari) показали нам свои недостатки. Как мы можем наблюдать, word-spacing в этих браузерах вообще не сработал, как будто бы мы его и не назначали. Поведение webkit-ов в данной ситуации, скорее всего, можно назвать багом, так как свойство, которое мы тут применяли, предназначено именно для межсловных расстояний. Доказательством в пользу бага служит то, что для обычных inline элементов word-spacing как раз таки работает в webkit так, как и должен, а вот для inline-block-ов к сожалению нет.

Первый вопрос, который вы зададите, будет: "А есть ли решение у данной проблемы?". С радостью отвечу вам, что ДА! И, как, ни странно, этим решением является снова наш старый, добрый display:table, который помог нам при проблемах в Safari, во втором варианте с font-size. Так что смело добавляем это правило и смотрим результат.

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

	/* Выставляем родителю значение -.36em */
	word-spacing: -.36em;

	/* Лекарство для webkit */
	display: table;
}
	ul li {
		display : inline-block;
		width : 100px;
		border : 1px solid #E76D13;

		/* Возвращаем в нормальное состояние у потомков */
		word-spacing: normal;

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


image

Да, вы не ошиблись. display: table действительно помог нам решить баг webkit-ов. Недостатки этого лечения, собственно точно такие же, как я приводил во-втором варианте, т.е. это позиционирование и задания ширины в контейнере. В остальном этот способ я лично считаю более уместным, чем все предыдущие предшественники, так как, во-первых, мы всё таки решаем проблемы с межсловным расстоянием (word-spacing как раз и создан для этого), во-вторых, решение для проблемы webkit-ов вполне безобидное, если не считать пару нюансов, ну и в-третьих, я, тестировал этот метод с разными размерами шрифта и даже тут ничего страшного не заметил. Так что привожу работающий пример, смотрим и идём далее...

Результат с word-spacing

Вариант 5, 6 — Соединение элементов


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

HTML первого варианта:


<ul><li>Пункт 1</li><li>Пункт 2</li><li>Пункт 3</li><li>Пункт 4</li><li>Пункт 5</li></ul>


Ну и второго соответственно:


<ul><!--
	--><li>Пункт 1</li><!--
	--><li>Пункт 2</li><!--
	--><li>Пункт 3</li><!--
	--><li>Пункт 4</li><!--
	--><li>Пункт 5</li><!--
--></ul>


А CSS для обоих вариантов будет таким:

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

}
	ul li {
		display : inline-block;
		width : 100px;
		border : 1px solid #E76D13;

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


Ну и конечно же, скриншоты:

image

Как видно из кода, в первом варианте мы просто пристыковали элементы вплотную, перенеся закрывающие теги вплотную к открывающим. А во втором — поместили между границами элементов комментарии, заменяя ими наши пробелы. Т.е. фактически мы намеренно лишили элементы каких либо отступов между ними, специально соединив их разными способами. При этом, как можно заменить, у этих вариантов есть хороший плюс, для них не требуются никакие спец. свойства и костыли в CSS, они работают сами по себе, при чём во всех браузерах, начиная с IE6+.

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

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

Результат

Вариант 7


Как оказалось, на свете есть ещё более простое, а главное, абсолютно законное решение, которым я хочу поделиться. Дело в том, что любая спецификация HTML (но не XHTML), позволяет нам опускать закрывающие теги у некоторых элементов, т.е. разрешает их отсутствие. В спецификации HTML5 таких элементов целых 18 штук. Это означает, что мы, на вполне законных основаниях, можем пользоваться этим преимуществом. Ведь никто не запрещает нам это сделать, не правда ли?)
В нашем случае элементы <li> попадают в этот список, так что воспользуемся этим.


<ul>
	<li>Пункт 1
	<li>Пункт 2
	<li>Пункт 3
	<li>Пункт 4
	<li>Пункт 5
</ul>


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

}
	ul li {
		display : inline-block;
		width : 100px;
		border : 1px solid #E76D13;

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


image

Т.е. по сути, я просто опустил закрывающие теги </li>, и раз после содержимого первого элемента сразу же идёт открывающий тег второго, то соответственно и интервала между ними быть не должно. Что наглядно демонстрируется на скриншоте.

*Стоит заметить, что в IE6-7, например, опциональные закрывающие теги в списках всё равно игнорируются, поэтому там этот метод получается "автоматом". Именно из-за этого в первом варианте c отрицательным левым margin-ом, мы, отдельно, обнуляли margin-left для этих браузеров.
Этот способ мне кажется наиболее удачным, одновременно лёгким и удобным, чем все остальные, которые мы рассматривали в этой статье. Недостатком лишь стоит назвать то, что такую структуру не воспринимают любые XML-парсеры.

Вывод такой, что этот метод не подходит "фанатикам валидности ради валидности", выбирающим XHTML-доктайп, но практикам, ориентирующимся на современные спецификации и реальный результат, отказываться от такого решения незачем =)

Результат

Резюме:


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

Все варианты воедино:


1. Результат с margin-left (Почти рабочее решение)
2. Решение с font-size (Рабочее решение)
3. Результат с letter-spacing (Работающее решение)
4. Результат с word-spacing (Рабочее решение)
5. Вариант с намеренно прижатыми элементами (Рабочее решение)
6. Решение с незакрытыми тегами (Рабочее решение)

И, отдельно хочется сказать огромное спасибо моему дружищу SelenIT2, за помощь в поисках материала и написании статьи.

Upd: Запостил эту статью у себя в блоге.
Максим Усачёв @psywalker
карма
91,0
рейтинг 5,6
Пользователь
Похожие публикации
Самое читаемое Разное

Комментарии (141)

  • +4
    Есть подозрение, что парсер пожрал что-то важное при публикации html-кодов 5 и 7 вариантов.
    • +1
      Там не парсер, а автор по ошибке в 7-м варианте оставил закрывающие теги <li>, хотя рассказал об этом и до, и после, и не ошибся в демо-примере :).
      • +4
        А еще более интересно, как браузеры обрабатывают 7й вариант.
        • 0
          Всё правильно обрабатывают, в этом суть решения — тег автоматически закрывается, когда встречается другой подходящий тег. Т.е. все табы и переносы попадают внутрь.
          • 0
            Ну не совсем так. Так только у Firefox и что-то наподобие у Chrome, но вот у Opera имеются отступы.
            Хотя не в этом суть, главное, что этот метод полностью работает.
      • +2
        Дико ссори, статья очень обширная, поэтому чего-то и не доглядел. Исправил.
        • 0
          Обширная — это когда затронуты много тем. У вас тут затронута только одна. Статья просто не в меру большая.
          • 0
            статья збс, четко все рассказал
  • 0
    А зачем? Точнее так, статья хорошая — но действительно ли так критично это расстояние? Я использую inline-block только в горизонтальных меню с ul и li. Там эти расстояния, по моему, наоборот полезны.
    • +4
      Чтобы быть уверенным на 100%, что при вычислении ширины элементов, вы не ошибётесь на пару пикселей, из-за неучтённых пробелов.
      Сам использую {srtip}, в Smarty, для этих целей.
      Но в любом случае спасибо автору за эксперименты и информацию.
    • +3
      Поверьте моему опыту. Порой это расстояние доставляет массу неудобств, что собственно и натолкнуло меня на изучение данной проблемы.

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

  • 0
    Я сойду с ума, если прочитаю весь этот текст?

    За материал спасибо, но уж больно тернист путь к результату. Неужели нельзя было несколько короче?
    • +8
      Дело в том, что я так долго изучал вопросы из данной статьи, что материала накопилось очень много, а так как тема одна и таже, то и решил сделать всё одной статьёй.

      Советую читать понемногу, с передышками, чтобы усваивалось :)
      • –2
        Я вижу тут материал на 3 абзаца, остальное пережевывание уже сказанного. Где остальной материал?
        • +1
          А я вижу здесь очень много-много абзацев. И, если бы я ужал статью, как вы предлагаете, то никто бы кроме вас не понял бы суть многих вещей.
  • +4
    ВАЖНО! Если вы используете трюки типа display: table-cell/table, учтите, что их поддержка весьма кривая, во-первых у вас могут теряться маргины (правильно, какие могут быть маргины у ячеек таблицы), вы-вторых, браузеры автоматом для блока с table-cell могут добавить родительские анонимные блоки table-row и table, и как-то этим сломать верстку.

    По мне так, лучший способ — HTML комментарии, так как кроссбраузерно и сразу понятно, зачем они сделаны. Или, если не нужно вертикальное выравнивание, проще использовать флоаты и не париться.
    • НЛО прилетело и опубликовало эту надпись здесь
  • +6
    Статья хороша. Все подробно описано. Спасибо!
    • –11
      Статья плохая, на 90% состоит из воды.
      • +19
        К чему это, дружище? К данной статье я приложил кучу сил и времени, подробнейше изложив и разжевав всё до мелочей.
        Возможно для вас это и вода, кто бы спорил. Я вообще не знаю, что могло бы вас удивить, после чего вы воскликнули бы «Вау!». При всём моём уважении к вам, попрошу, не равняйте всех под свою гребёнку плз.
        • +4
          Зря ты так, homm ;) Таких глубоких и исчерпывающих статей по CSS очень мало.

          Если даже на главной странице Студии Лебедева для поставленной целей втыкают жуткую заскриптованную таблицу, которая вообще не отображается с отключенным JS, то эта статья очень актуальна.
          • +1
            >>> Зря ты так, homm ;) Таких глубоких и исчерпывающих статей по CSS очень мало.

            В том-то и дело, спасибо, что вы это понимаете и цените труд.
          • +1
            Очень актуальна. Но на 90% состоит из воды.
            • +1
              Ни процента воды, подробнейший анализ. Другое дело, что подобная скрупулезность годится для научных статей, а на хабре — не очень, все-таки проблема не дико актуальная (сравнить, например, с выебонами IE).
          • +1
            > Таких глубоких и исчерпывающих статей по CSS очень мало.
            Похоже на сарказм. Статья вообще-то об одной особенности одного конкретного свойства.
            • +1
              Имеется ввиду глубокий и исчерпывающий материал как раз таки по одной из особенностей инлайн элементов. Никаких сарказмов.
        • +1
          А при чем тут мое «вау»? Я указал на конкретны недостаток. Если бы статья был написана более сжато, она не потеряла бы полезности, но сил вы бы положили на нее меньше.
          • 0
            Да, полезности она бы не потеряла, возможно, не спорю, но и понятливости со стороны сообщества было бы в разы меньше. Вы очень опытный, а вот Вася с Петей — нет, для них наоборот нужно всё поподробнее разжёвывать, чтобы донести как надо.

            А потом, я и сам люблю копаться и рыться в материале досконально, а материала накопилось очень много, поэтому и выложил всё сразу.
            • +2
              Усваиваемость (понятливость со сторону сообщества) не улучшается при увеличении усваиваемого материала, а часто наоборот. Вот у вас в каждом способе есть скриншот, на котором все ок. Это же каждый раз приходится его смотреть, выяснять, все ли на нем ок, или вы хотите этим скриншотом показать что что-то отличается. А вот писали бы вы всегда «При таком способе проблемы появляются только в webkit: <скриншот>», и все сразу понятно.
              • +2
                Спасибо за ценные советы, я постараюсь вынести урок из ваших слов. Но, не факт, что от этого мои статьи будут меньше, у меня всегда получается как-то всё разжёвано очень)
      • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Извиняюсь, не туда воткнул каммент.
        habrahabr.ru/blogs/css/137582/#comment_4584132
    • +2
      Рад был помочь. Изучайте!
  • +13
    Я всегда лечу через «заворот кишок»:
    <ul
         ><li>Item 1</li
         ><li>Item 2</li
         ><li>Item 3</li
    ></ul>
    
    • +2
      Оригинально =) И название подходящее.
      • +1
        отличие от комментария — комментарий остаётся в IE как пустая текст-нода, тогда как «разорванный тег» эквивалентен записи всего в одну строку для всех браузеров.
        • +3
          Надо бы добавить этот вариант в пост как «самый-самый».
  • 0
    Спасибо за статью! Я же всегда пользуюсь 5 способом и проблем не знаю. Очень люблю применять inline-block для верстки, особенно для вывода каталога товаров. Правда я чаще пишу так:
    • Item1
    • Item2


    Пробелы внутри блоков уже схлопываются, а между ними их нет.
    • +2
      Извините:
      <ul>
          <li>
             Item1
          </li><li>
             Item2
          </li>
      </ul>
  • 0
    Ещё есть вариант с «float: left», правда у него тоже свои недостатки.
    • +1
      Да, есть ещё на «position: absolute» и т.д, но эти вещи уже выходят за рамки статьи ;)
      • +1
        не-не, не надо из потока вырываться :)
    • 0
      Вариант есть, но как таким способом сделать горизонтальное меню, например, выровненное по центру?
      • 0
        margin: 0 auto;?
        • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          При float: left; левый маргин внезапно обнулится
  • +1
    Приветствую тебя на Хабре, «дружище»! Хорошая первая статья для начинающих, так держать!

    З.Ы. Лично для себя обычно использую комбинацию этого всего:

    UL {
       font:0/0 a;
       letter-spacing:-1em;
       word-spacing:-1em;
    }
        UL LI {
            font:12/16px Arial, sans-serif;
            letter-spacing:0;
            word-spacing:0;
        }
    


    При этом если вдруг захочется выравнивать элементы с помощью text-align:justify; то тут могут быть неприятные сюрпризы в Chrome, Opera и Safari. Впрочем, играя с размером шрифта их можно обойти.
  • +2
    С комментариями решение самое оптимальное — не нужно гадать, какой шрифт в меню и какой есть у пользователя, подстраиваться под браузеры и самое важное — в меню могут быть вложенные элементы (подменю например) — им не нужно выставлять обнуленные у родителя значения (в случае font-size=0 у родителя, потомку придется задавать font-size только в пикселях)
  • +1
    Лично для меня статья оказалась очень интересна и полезна. Спасибо!
    Небольшое предложение автору для будущих исследований: было бы интересно развить эту тему и узнать о построении кроссбраузерного горизонтального меню, которое находится в резиновой верстке и при этом выровнено по центру блока. И как вариант равномерно растягивается по ширине. Я в сети видел много различных решений, сам придумывал свои велосипеды, однако глубоко и полно этот вопрос так и не разобрал.
    • +1
      Рад, что труды оказались не напрасны. Рад был поделиться знаниями.

      По поводу вашего предложения:
      Если не сложно, то скиньте мне в ЛС пример того, что вы имеете ввиду, возможно я уже роюсь в этом направлении.
      Единственное, не факт, что публиковаться я буду именно на Хабре, я недавно открыл свой личный блог, где и буду разбирать все вопросы в своих постах. Так что, если что, добро пожаловать, буду рад помочь!
  • 0
    Спасибо, статьяна очень интересна и актуальна, буквально вчера как раз верстал с помощью inline-block, для себя решил отрицательными значениями margin, но сейчас исправлю на комментарий, симпатичнее выглядит.
  • +1
    последний вариант гениален. Как раз то, что я искал. Не люблю костыли городить.
  • 0
    Спасибо большое за статью.
    Но, всё таки, самый практичный вариант это 5й, тем более, что полезно удалять [\n, \t, комментарии, двойные пробелы] перед выдачей html-файла клиенту.
  • –1
    Серебренная пуля:
    ul {
        letter-spacing: -0.31em; /* webkit: collapse white-space between units */
        *letter-spacing: normal; /* reset IE < 8 */
        word-spacing: -0.43em; /* IE < 8 && gecko: collapse white-space between units */
    }
    
    li {
        display: inline-block;
        zoom: 1; *display: inline; /* IE < 8: fake inline-block */
        letter-spacing: normal;
        word-spacing: normal;
    }
    
    

    Стех пор как подсмотрел в YUI CSS Grids, оно меня еще ниразу не подводило
    • 0
      Свойство zoom не канонично, хорошо бы спрятать.
      • 0
        Чем же оно не канонично, и можно ссылку на «каноны»?
        • 0
          Разумеется, наслаждайтесь.
          • +1
            Тогда все браузерные проприетарные перфиксы — против «канонов», text-overflow — против «канонов», text-shadow — против «канонов», анимации, трансформации — всё против «канонов»?
            А ведь zoom — это не только MSIE only свойство, webkit его тоже поддерживает.
            • 0
              Проприетарные префиксы этично использовать для совместимости с предыдущими версиями, причем с поправкой на ограниченную видимость для остальных библиотек. Добавлять в код нестандартные и некомментируемые элементы — значит рисковать работоспособностью написанного в дальнейшем. Вы же не можете быть уверены, что в следующей спецификации не введут определение zoom с совершенно другими свойствами, чем те, которые вы ожидаете увидеть на каких-то отдельных движках сегодня.

              Поэтому говорить что «ну ведь сейчас-то работает» непрофессионально. О чем я вам и постарался аккуратно намекнуть.
              • +1
                text-overflow не включен в драфт по css3 — прикажете не использовать?

                И да, я скорее уверен, что zoom появится в спецификации (Гугл пропихнет).
            • НЛО прилетело и опубликовало эту надпись здесь
              • +1
                Я какбы не спорю с тем, что можно и прикрыть, я спорю с «канонами». Сам я ставлю зведочку перед zoom, а код я привел из YUI не изменяя.
            • 0
              > А ведь zoom — это не только MSIE only свойство, webkit его тоже поддерживает.
              Пруф?
              • НЛО прилетело и опубликовало эту надпись здесь
                • 0
                  Омг, это правда, и до сих пор работает.
      • +1
        Для статьи делать это совершенно ни к чему, читатели должны видеть весь код, а ни держать всякие zoom-ы в уме*, а уже в своих проектах вы вольны делать так, как хотите. Конечно же, правильно было бы отправить это свойство в условные комментарии, но в статье это необязательно.
        • 0
          Читатели должны видеть прежде всего корректный синтаксис в соответствии с действующими спецификациями. Свойство 'zoom' таковым не является.
          • 0
            Пишите это к каждой статье про CSS3 и HTML5.
            • 0
              А каким образом CSS3 и HTML5 относятся к данной статье?
              • 0
                Не к статье, а к вашим словам «корректный синтаксис в соответствии с действующими спецификациями». CSS3 и HTML5 не имееют «действующих спецификаций» только черновики.
                • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            Хорошо ещё, что я не применял префиксы, иначе вы бы меня съели вообще)
            • 0
              Предпочитаю растительную пищу человечине.
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              В данном случае overflow-wrap будет алиасом word-wrap, что, в принципе, логично, т.к. подразумевается перенос не в рамках слова, а в рамках элемента. Отменять устаревшее значение пока никто не собирается.

              А вот каких свойств можно ожидать от zoom — непонятно.
              • НЛО прилетело и опубликовало эту надпись здесь
                • –1
                  Перенос в рам-
                  ках слова ниче-
                  го общего не име-
                  ет с word-wrap.

                  От недокументированного свойства можно ждать чего угодно, в качестве примера: даже если вы интуитивно предугадали действие, в каких единицах по умолчанию будет считаться свойство? Проценты? Пункты? Пиксели? Не рискуете ли автор наделить меню с 'zoom:1' размером в 1% от родительского элемента?

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

                  А в целом я очень не хочу развивать полемику о достоинствах и недостатках таблиц стилей и предлагаю вернуться к изначальному предложению писать грамотно. Всего-навсего.
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • +1
                      Среди американских программеров была такая бородатая шутка про w3c, который семантически правильнее было бы сокращать как 3wc, а аббревиатура wc известна всему миру как water closet. Отсюда и прозвище «три туалета».
                      • НЛО прилетело и опубликовало эту надпись здесь
                  • НЛО прилетело и опубликовало эту надпись здесь
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        А вот за этот случай спасибо, буду держать в уме :)
        • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            а, вот почему я и не столкнулся с этой проблемой. zoom и display:inline я приминяю только для болчных элементов
            • НЛО прилетело и опубликовало эту надпись здесь
    • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    Свойство zoom не канонично, хорошо бы спрятать.
  • +1
    Вы — большой молодец. Продолжайте в том же духе.
    • +1
      Спасибо за слова, но, к сожалению, у меня всегда очень мало времени даже на себя, а про написании статей я уже вообще молчу(((. Здесь мне удалось удивительным образом выкроить время и поделиться своими знаниями с сообществом. Воспользовался так сказать, возможностью. Да, и, опять же, у меня ещё сырой блог, поэтому для начала желательно заполнить статейками именно его.
      • 0
        В любом случае я буду следить за вами =)
        • 0
          =)
  • 0
    Спасибо за статью! Эх, часика на три бы пораньше ))…
    Как раз около полуночи с этими невесть откуда взявшимися 6 пикселами страдал ( ну да, в вёрстке новичок… ). В итоге пришёл к варианту 5. Но всё равно, прочитал статью с интересом ;)…
    • +1
      Эх, что ж вы мне не позвонили, я бы вам подкинул идеек :)
  • +1
    С почином, Макс! Молодец!
    • 0
      Сенкс)
  • 0
    Хм. Всё замечательно, но я бы верстал такое «меню» через display: block и float: left
    Или есть какая-то определенная потребность в inline-block, кроме демонстрации решения?
    • +1
      1) float: left уже делает элемент блочным.
      2) Прочитайте внимательно, о чём статья.
      • 0
        Я прочитал. Не хочу лезть в бутылку, но в части статьи «Почему в статье я использую именно inline-block?» вижу только демонстрационные цели. Так что, по-моему, выбор такого предмета, как меню, в качестве примера в данном случае не очень удачное…
        • +1
          Цель статьи — это понять, что из себя представляют «загадочные» отступы между инлайн-элементами (акцент на них), и рассмотреть разные способы, варианты решения и разжевать всё подробно.
          • 0
            Да, статья отличная.
      • 0
        Не делает, а придаёт ему блочные свойства.
        • НЛО прилетело и опубликовало эту надпись здесь
        • +1
          Я имел ввиду, что при float: left от display: block уже не будет никакого смысла.
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Ну, вот это, пожалуй, и есть причина для использования inline-block.
        • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            Я вот не настолько опытен, как вы и автор, поэтому, наверное, стоило бы описать область применения этого свойства, для таких, как я.
  • 0
    inline-block, как видно из названия, умудряется сочетать свойства инлайнового (внутристрочного) и блочного элементов: внутри он блочный (может содержать другие блоки


    Что Вы хотели этим сказать? Запрет на вложение блочных элементов в строчные определён в HTML, он безразличен к тому, что написано в CSS-стилях. То есть вот так неправильно: <span style="display: inline-block;"><div></div></span>

    Вывод такой, что этот метод не подходит «фанатикам валидности ради валидности», выбирающим XHTML-доктайп


    Вы зря изображаете каких-то идиотов. Не ради валидности — с валидностью-то (по HTML5) тут всё в порядке, как Вы правильно отметили,— а ради XML-конформности, а оная нужна для упрощения парсинга, например.
    • НЛО прилетело и опубликовало эту надпись здесь
      • +1
        Где тупые браузеры не умеют получать странички в mime-type отличном от text/html… Список тупых браузеров, думаю известен всем…
      • 0
        Во-первых, не «в HTML больше нет», а в HTML5 больше нет. Если даже Вы полагаете, что более новый стандарт отменяет более старый (что, строго говоря, неверно, но с чем я соглашусь как с допустимым упрощением), HTML5 не стандарт, а проект и это, увы, ещё надолго.

        Во-вторых, если Вы рассуждали относительно HTML5, то Ваше утверждение также неверно, поскольку, хотя в HTML5 и другие модели содержимого, но и там CSS-стили на них не влияют. Элемент может вкладываться в другой или нет независимо от того, какой им прописывать стиль [display].
        • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            Ну. Тогда как следует понимать Ваше утверждение, что, де, элемент с display: inline-block «может содержать другие блоки», если способность элементов содержать что-либо никак не зависит от задаваемых им стилей?

            В общем, ситуация, по моему, совершенно ясна: Вы неудачно выразились в этом моменте.
            • НЛО прилетело и опубликовало эту надпись здесь
              • –1
                Запреты на вложенность блочных элементов в строчные определён в HTML4. Поэтому я и пытаюсь перевести разговор на модели содержимого в HTML. А если речь идёт о визуальных боксах, определённых в CSS, то там нет запрета на вложенность. С чего Вы взяли, что инлайновые боксы не могут содержать блочные боксы? Легко!

                <?xml version="1.0" encoding="UTF-8"?>
                <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
                <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru">
                	<head>
                		<title>Пример</title>
                	</head>
                	<body>
                		<p style="display: inline;"><span style="display: block;"></span></p>
                	</body>
                </html>
                
                • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Те, кому нужен XML-парсинг собственных страниц (зачем, кстати?)


        Почему обязательно собственных? А о других людях подумать?

        слегка отрезвить и вернуть «из страны иксэмэльфов» в реальный мир, где браузеры получают странички как text/html…


        Вы опрометчивы, полагая, что реальный мир сводится к Вашей практике. В области моей разработки страницы испокон веку отдаются как application/xhtml+xml или даже application/vnd.mozilla.xul+xml.
        • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            О других людях подумали разработчики современного алгоритма HTML-парсинга


            Угу-угу, и алгоритм сей настолько прост, что отладить его намечено уже к 2022 году.

            разве в области *.mozilla.xul проблема выстраивания блочных боксов по горизонтали не решается более специализированными инструментами, чем инлайн-блоки?..


            На XUL там пока только небольшой фрагмент и неизвестно, будет ли сильно больше. Остальное — честный XHTML 1.1. Буду переводить на XHTML5, конечно. Занялся бы этим раньше, но в проекте был двухлетний перерыв в связи с кризисом, да и делался он прежде под очень старую версию браузера.
            • НЛО прилетело и опубликовало эту надпись здесь
              • 0
                И где PHP-метод для разбора HTML в DOM-дерево?
                • НЛО прилетело и опубликовало эту надпись здесь
                  • 0
                    С XHTML, однако, у PHP никаких проблем нету. Ну, почти никаких. Так что не вижу смысла отказываться от XML-синтаксиса при использовании HTML5. Ну, разве что кто-то так и не приучился к нему в прежние времена. Ну так есть люди, не приучившиеся деепричастные обороты обособлять запятыми,— почему я должен брать с них пример и радоваться упрощению жизни?
                    • НЛО прилетело и опубликовало эту надпись здесь
                      • 0
                        На практике этот метод засыпал меня уорнингами, пока я не
                        libxml_use_internal_errors(true)
                        . Ну и XPath к HTML’у не применишь.

                        XHTML делает тэг-суп с неожиданными порой последствиями невозможным и приучает его не допускать, в чём его великая историческая заслуга. А в этом HTML поди вспомни, какой тэг можно не закрывать, а какой нельзя. Лучше уж закрывать все и спать спокойно.
                        • НЛО прилетело и опубликовало эту надпись здесь
                          • 0
                            Не гарантировать, но процентов на восемьдесят обезопасить — уже хорошо.
                            • НЛО прилетело и опубликовало эту надпись здесь
  • +1
    Какие-то странные и витиеватые у вас обоснования для этих пробелов.
    Из которых нечайно даже можно сделать неверный вывод, что inline-block элементы интерпретируются как слова, а между словами автоматически вставляются междусловные интервалы.

    По всем мыслимым стандартам, разрыв строки — это пробел, whitespace.
    Если любой пробел стоит, то он отображается как пробел.
    Если никакого пробела не стоит, пробел не отображается.
    (в текстовом контексте, для которого не указано всякое 'pre').

    Вот и всё. И так было всегда.
    • НЛО прилетело и опубликовало эту надпись здесь
    • +1
      inline-block смело можно рассматривать, как одну большую букву, причём неразрывную. Так же как и буквы могут иметь пробелы между собой, так и инлайн-блоки тоже не обделены этой особенностью.
      Про «автоматизм» я вроде нигде не упоминал, а как раз таки наоборот, описал ситуацию с пробелами в случае разрыва строки в структуре. Перевод строки — который преобразуется в пробел. Всё верно, поэтому я не понимаю, что вам могло показаться не так.
      • +1
        Мистифиакция этих пробелов и избыточные объяснения откуда они берутся.
        • НЛО прилетело и опубликовало эту надпись здесь
        • +1
          А как по мне, так наоборот, очень подробное объяснение + изображения для наглядности. Вы первый, кому это показалось непонятным и запутанным.
    • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Не всегда. Пробел убирается в конце line-box'а, игнорируется между блочными элементами, и еще много-много вариантов, когда пробел не пробел.
  • 0
    я пару лет назад писал об этом.
    habrahabr.ru/blogs/css/51297/
    но мне не верили :))
  • 0
    Чем «работающее» решение отличается от «рабочего»?
    • +1
      Ничем. Это я к концу статьи уже устал очень. Посмотрите на объём!
      • 0
        Спасибо, я уж думал градация какая-то (=

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.