Inline block убрать отступы: html — Отступы между инлайновыми элементами

Долой отступы между строчными элементами (и блоками)

Автор: Александр Головко Дата публикации:

Строчные блоки (inline-block) во многих случаях очень удобное средство разметки. Примеры их использования можно посмотреть в статьях Inline-block: простое свойство для непростых задач, Выравнивание навигации из блоков по центру, Центрирование резинового блока по горизонтали.

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

Допустим имеем такой HTML:


	<ul>
		<li>Стороки.</li>
		<li>Просто</li>
		<li>строки</li>
	</ul>

Делаем элементы строчными:


li{
	display:inline;
}

…или строчными блоками:


li{
	display:inline-block;
	/* Следующие две строки для IE6-7 - эмулируем поведение строчного блока*/
	//display:inline; 
	zoom:1;
}

Проблема

Большинство браузеров разделяет строчные блоки (элементы) отступами. Для удобства восприятия я немного раскрасил блоки.

Опаньки! Что за отступы? Я ничего такого не прописывал!

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

Кого лечим?

Итак строчные блоки обзавелись загадочными отступами. Конечно, это касается не только списков. Так же поведет себя и группа расположенных подряд, например, span’ов.

Справедливости ради, следует заметить, что IE6 и IE7 отрисуют все это дело без отступов:

Вот так хочу, чтобы все браузеры отображали!

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

На самом деле все просто — чтобы убрать отступы, нужно понять, откуда они там вообще взялись!

Откуда отступы-то?

А понять не сложно. Достаточно просто записать теги в одну строку:


	<ul>
		<li>Стороки.</li><li>Просто</li><li>строки</li>
	</ul>

Чудеса! Отступы пропали сами собой! Вывод: порождают их невидимые символы между тегами — перенос или пробел.

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

Долой отступы!

Раз отступы создают символы из контейнера, здравой мыслью будет эти символы «обезвредить» — задать им font-size:0; (главное, не забыть, что это свойство наследуется и перебить его для самих потомков):


ul{
	font-size:0;
}
li{
	font-size:14px;
	display:inline;
}

Отличное решение! Строчные блоки действительно прижались друг к другу. Осталась еще небольшая косметическая проблема: в некоторых браузерах (например, в Opera 9. 5 и младше) замечен отступ сверху или снизу в пределах родителя (родитель на рисунке залит бледным серо-зеленым):

картинка увеличена, чтоб было видно отступы по вертикали

Проблема эта сродни описанной в статье IMG внутри блока — убираем странный отступ, и лечится примерно так же: добавляем line-height:0; (опять не забываем перекрыть у потомка). Итак, получаем:


ul{
	font-size:0;
	line-height:0;
}
li{
	font-size:14px;
	line-height:normal; /* ну или другое подходящее значение */
	display:inline;
}

Теперь-то все хорошо и красиво? Не тут-то было!

Пришла беда, откуда не ждали

Видать, действительно эти отступы должны быть! В подтверждение этому есть два железных аргумента:

  1. их не рисует IE6-7;
  2. их, несмотря на наши старания, все равно рисуют Webkit-браузеры.

Да-да! И Safari и Chrome после всех вышеизложенных ухищрений соизволили просто уменьшить отступы с трех пикселей до одного!

Упрямые webkit’ы не хотят сдаваться!


Update by Nick. Еще один скрытый сюрприз преподнес FF. Если масштабировать страницу иногда наблюдается дополнительный отступ в 1px сверху. Лечится это добавлением правила display: -moz-inline-stack;

Окончательное решение

Побороть webkit’ы получилось с помощью letter-spacing:-1px. При этом никаких вредных побочных эффектов обнаружено не было (если, конечно не забыть перекрыть свойство у потомков).

Окончательный CSS с кроссбраузерным решением для строчных элементов:


ul{
	font-size:0; /* убираем горизонтальные отступы */
	line-height:0; /* ...и вертикальные в некоторых браузерах */
	letter-spacing:-1px; /* переубеждаем webkit'ы */
}
li{
	font-size:14px; /* Не забываем восстановить нормальные значения */
	line-height:normal;
	letter-spacing:normal;	
	display:inline;
}

Для строчных блоков:


ul{
	font-size:0; /* убираем горизонтальные отступы */
	line-height:0; /* ...и вертикальные в некоторых браузерах */
	letter-spacing:-1px; /* переубеждаем webkit'ы */
}
li{
	font-size:14px; /* Не забываем восстановить нормальные значения */
	line-height:normal;
	letter-spacing:normal;
	display: -moz-inline-stack!important;
	display:inline-block;
	//display:inline;
	zoom:1;
}

Не забудь, что свойство zoom невалидно. Поэтому в боевых условиях выноси его и хак для IE в отдельный CSS, подключаемый с помощью условных комментариев.

Демонстрационный пример

Проверено в:

  • IE 6-8
  • Firefox 3.5
  • Opera 9.5-10.5
  • Safari 4
  • Chrome 7

Очистка float`ов |

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

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

Есть несколько способов для решения этой проблемы. Раньше мы использовали пустой div со стилем «clear: both» в самом низу контейнера. Затем, мы заменили его на тег hr, что не на много лучше.

И наконец Nicolas Gallagher предложил новый путь очистки float`ов без необходимости трогать разметку совсем. После продолжительных дискуссий и тестов, мы получили минимально необходимый, для его работы, набор стилей, вот его последняя версия:

Код:

.clearfix:after {
    content: "";
    display: table;
    clear: both;
}

На самом деле я солгал, она не последняя, она самая короткая. Но если вам нужна поддержка IE 6/7, то вам нужно добавить еще вот это:

Код:

.clearfix {
    *zoom: 1;
}

Для работы необходимо добавить класс .clearfix в свой проект, а затем применять его к элементам разметки. Это самый простой и чистый способ для работы с float`ами.

Как победить отступы между элементами с inline-block?

Продолжим с размещением элементов в строку, в этот раз не с помощью float, а с помощью inline-blocks. display: inline-block долгое время был недооценен, и все же мы разобрались, как он работает и почему это круто. Сегодня, все больше и больше front-end разработчиков предпочитают использовать inline-block взамен float`ов, когда у них есть такая возможность.

Главный плюс inline-block в том, что нам не приходится отчищать float`ы и мы не сталкиваемся с другими проблемами которые могут возникнуть из-за элементов спозиционированных с помощью float`ов. Просто установив свойство элемента display в значение inline-block получим гибрид строчного элемента и блока. Они могут иметь размер, отступы, но их ширина, по-умолчанию, зависит от контента, а не занимает всю ширину родителького элемента. Таким образом они размещаются горизонтально, а не вертикально.

Вы можете спросить: «В чем же тогда проблема?». А проблема в том, что они на половину строчные, а значит имеют отступ друг от друга размером равным пробелу. Со стандартным шрифтом размером 16px, он составляет 4px. В большинстве случаев размер отступа можно рассчитать, как 25% от размера шрифта. Так или иначе, это может помешать нормальному расположению элементов. Например, возьмем контейнер размером в 600px с тремя элементами внутри, размер которых 200px и задано свойством display: inline-block. Если не убрать отступ, то нам не удастся разместить их в одну линию (200 *3 + 4 * 2 = 608).

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

Уровень разметки: удаление пробелов

Для всех наших тестов воспользуемся следующей разметкой.

Код:

<div> <!-- 600px -->
    <div>I'm a child!</div> <!-- inline-block 200px -->
    <div>I'm a child!</div> <!-- inline-block 200px -->
    <div>I'm a child!</div> <!-- inline-block 200px -->
</div>

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

Код:

<div>
    <div>I'm a child!</div><div>I'm a child!</div><div>I'm a child!</div>
</div>

Это действительно работает, но делает не удобным чтение нашего кода.

Хотя, мы можем, немного реорганизовать наши элементы, что бы сохранить читаемость:

Код:

<div>
    <div>
        I'm a child!</div><div>
        I'm a child!</div><div>
        I'm a child!</div>
</div>

И если быть уж совсем крутым, можно сделать и так:

Код:

<div>
    <div>I'm a child!</div
  ><div>I'm a child!</div
  ><div>I'm a child!</div>
</div>

Да — это работает! Конечно я не рекомендую такой подход, потому что он не интуитивен и делает код уродливым. Давайте, лучше, попробуем, что нибудь еще.

Уровень разметки: комментируем пробелы

Что если закомментировать пробелы вместо того, что бы удалить их?

Код:

<div> <!-- 600px -->
     <div>I'm a child!</div><!-- 
--><div>I'm a child!</div><!--
--><div>I'm a child!</div>
</div>

Да, так гораздо лучше! Код читаем и работает. Да, способ выглядит не привычно на первый взгляд, но не так и сложно к нему привыкнуть. Я и сам использую такой способ, когда мне надо удалить пробелы между элементами с inline-block.

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

Уровень css: расстояние между символами

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

Код:

.parent {
    letter-spacing: -0.3em;
}
 
.child {
    letter-spacing: normal;
}

Эта техика используется в Griddle — основанной на Sass системе сеток за авторством Nicolas Gallagher, так что, как вы видите, это достаточно серьезное решение. Хотя, честно говоря, мне не нравится тот факт, что мы полагаемся на магические числа в стилях. Плюс с некоторыми шрифтами, это число может меняться например на 0.31em и т.д. То есть, его необходимо подгонять под каждый конкретный случай.

Уровень css: отрицательный margin

Еще один подход к решению задачи, очень похож на предыдущий, но с использование отрицательного отступа. Главный его недостаток он не работает в IE 6/7. Плюс нам необходимо убрать отступ с первого элемента, что бы они ровно встали внутри нашего контейнера.

Код:

.child {
    margin-left: -0.25em;
}
 
.child:first-of-type {
    margin-left: 0;
}

Если вам не требуется поддержка IE 6/7, я считаю что это достаточно неплохое решение.

Уровень css: font-size

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

Код:

.parent {
    font-size: 0;
}
 
.child {
    font-size: 16px;
}

У этого решения есть несколько своих проблем и ограничений:

  • Вы не сможете восстановить шрифт для дочерних элементов используя em как размер шрифта
  • Пробелы не удаляются на устройствах с Android до Jellybean
  • Текст с использование @font-face может потерять сглаживание в Safari 5
  • Некоторые браузеры игнорируют font-size: 0, например Китайская версия Chrome, в таком случае font-size сбрасывается до 12px

Так что, это не лучшее решение. Как я уже говорил ранее, скорее всего буду использовать путь с комментирование пробелов. Если для вас он выглядит неудобным, вы можете вернуться к float`ам или же вообще использовать flexbox.

Понимание абсолютного позиционирования.

Позиционирование элементов — каверзный процесс и всегда им был. Позиционирование, начинающим, дается с большим трудом. Они часто (не)используют свойство position. Это свойство определяет как элемент может перемещаться с помощью смещений (top, right, bottom and left). И принимает следующие значения:

  • static — по-умолчанию, смещения не действуют
  • relative — смещения двигают визуальный слой, но не сам элемент
  • absolute — смещения двигают элемент внутри контекста (первый не static элемент)
  • fixed — смещения позиционируют элемент внутри viewport`a и не важно где он расположен в документе

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

Код:

element {
    position: absolute;
    top: 0;
    right: 0;
}

… а он оказывается в верхнем правом углу документа. У вас промелькает мысль «Какого черта?». На самом деле, это нормальное поведение браузера. Ключевое слово тут контекст.

Код выше просто говорит: «Я хочу что бы мой элемент был спозиционирован в верхнем правом углу контекста». Так что же такое контекст? Это первый элемент со свойством position не равным static. Это может быть непосредственно родительский элемент, или родитель родителя, или родитель родителя родителя. И так до первого элемента с position != static.

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

Небольшая демка иллюстрирующая вышесказанное. Два родителя, в каждом по одному дочернему элементу спозиционированному абсолютно со смещение top: 0 и right: 0. Слева правильный родитель с position: relative, справа неправильный с position: static.

jsFiddle

html. Как устранить пробелы между встроенными элементами в CSS?

Задавать вопрос

спросил

Изменено 9 лет, 5 месяцев назад

Просмотрено 43к раз

У меня есть div с кучей тегов изображений внутри, вот пример:

 <дел>
     jpg" alt="Foo1" />
    Foo2
    Foo3

Поскольку между тегами есть пробелы, браузеры будут отображать некоторые пробелы между изображениями (Chrome выбирает 4 пикселя). Как я могу сказать браузеру, чтобы между изображениями не отображалось НИКАКИХ пробелов, не размещая > и < непосредственно рядом друг с другом? Я знаю, что межбуквенный интервал применяется в дополнение к тому, что решит использовать браузер, так что это бесполезно даже с отрицательным значением. По сути, я собираюсь сделать что-то вроде Твиттера в нижней части своей домашней страницы. Я посмотрел на их код, и они используют неупорядоченный список. Я мог бы просто сделать это, но я хотел бы получить техническое объяснение того, почему, по-видимому, нет способа устранить пустое пространство между этими изображениями.

  • html
  • css
  • пробел
  • удаление пробелов

2

Если вы по какой-то причине хотите это сделать:

  • без использования float s, и;
  • без свертывания пробелов в вашем HTML (что является самым простым решением, и для чего оно стоит, что делает Твиттер)

Вы можете использовать решение отсюда:

Как убрать пробел между элементами встроенного блока?

С тех пор я его немного усовершенствовал.

См.: http://jsfiddle.net/JVd7G/

межбуквенный интервал: -1px для исправления Safari.

 раздел {
    размер шрифта: 0;
    межбуквенный интервал: -1px
}
<дел>
    Foo1
    Foo2
    Foo3

0

Простейшее решение, не искажающее макет и сохраняющее форматирование кода:

 
Foo1Foo2Foo3

5

попробуйте добавить img {margin:0;padding:0;float:left}

другими словами, удалите все стандартные margin и padding браузеров для img и float их.

Демонстрация: http://jsfiddle.net/PZPbJ/

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

Встроенные элементы отображаются вместе с текстом.

1

Вы также можете сделать все привязки плавающими влево и установить для поля слева значение -1

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

3

Если вы обслуживаете свои страницы с помощью Apache, вы можете использовать модуль Google PageSpeed. Здесь есть параметры, которые вы можете использовать для свертывания пробелов:

http://code.google.com/speed/page-speed/docs/filter-whitespace-collapse. html

Вам не нужно использовать более «опасные» параметры PageSpeed.

Также см. ответы на этот вопрос о том, как удалить пробелы в CSS:

Игнорировать пробелы в HTML

Добавьте style="display:block" к тегам img .

html — Как добавить пробел между элементами встроенного блока?

спросил

Изменено 7 лет, 6 месяцев назад

Просмотрено 24к раз

Чтобы было ясно, я не хочу удалять пространство между элементами встроенного блока — я хочу добавить его.

Я хочу иметь сетку пунктов меню, которые могут иметь 2, 3 или 4 пункта в строке, чего я хотел бы добиться с помощью медиа-запросов.

Как я могу добавить пространство между элементами li, но при этом не иметь полей слева и справа в каждой строке ? (Заполнение не исправит это. ) Могу ли я добиться этого, используя только CSS?

 * {
  -webkit-box-sizing: рамка-бокс;
  -moz-box-sizing: рамка-бокс;
  box-sizing: граница-коробка;
  граница: сплошная 1px;
  размер шрифта: 0;
}
#основной {
  максимальная ширина: 450 пикселей;
  поле: 0 авто;
}
.элемент {
  отображение: встроенный блок;
  ширина: 200 пикселей;
}
.элемент изображения {
  ширина: 200 пикселей;
}
.clearfix {
  переполнение: авто;
}
ли {
  тип стиля списка: нет;
} 
 <дел>

  
  • <дел> Портреты Греции в ее истории кризис
  • <дел> Портреты Греции в ее истории кризис
    • HTML
    • CSS

    1

    Возможно, это поможет вам

     <стиль> * {
     -webkit-box-sizing: рамка-бокс;
     -moz-box-sizing: рамка-бокс;
     box-sizing: граница-коробка;
     граница: сплошная 1px;
     размер шрифта: 0;
    }
    #основной {
     максимальная ширина: 452 пикселя;
     поле: 0 авто;
    }
    . элемент {
     отображение: встроенный блок;
     ширина: 150 пикселей;
    }
    .item1 {
     отображение: встроенный блок;
     ширина: 150 пикселей;
     отступ: 0px 4px;
    }
    .элемент изображения {
     ширина: 200 пикселей;
    }
    .clearfix {
     переполнение: авто;
    }
    ли {
     тип стиля списка: нет;
    }   <тело> <дел>
  • <дел> Портреты Греции в ее истории кризис
  • <дел> Портреты Греции в ее истории кризис
  • <дел>