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

Учитывая этот HTML и CSS:

span {
    display:inline-block;
    width:100px;
    background-color:palevioletred;
}
<p>
    <span> Foo </span>
    <span> Bar </span>
</p>

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

Демо: http://jsfiddle.net/dGHFV/

Я понимаю, почему это происходит, и я также знаю, что я мог бы избавиться от этого пространства, удалив пустое пространство между элементами SPAN в исходном коде HTML, например, так:

<p>
    <span> Foo </span><span> Bar </span>
</p>

Тем не менее, я надеялся на решение CSS, которое не требует подделки исходного кода HTML.

Я знаю, как решить эту проблему с помощью JavaScript - удалив текстовые узлы из элемента контейнера (абзаца), вот так:

// jQuery
$('p').contents().filter(function() { return this.nodeType === 3; }).remove();

Демо: http://jsfiddle.net/dGHFV/1/

Но можно ли решить эту проблему с помощью только CSS?

35 ответов

Решение

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

Давайте не будем забывать фактический вопрос, который был задан:

Как убрать пробел между элементами inline-block? Я надеялся на решение CSS, которое не требует подделки исходного кода HTML. Можно ли решить эту проблему с помощью только CSS?

Эту проблему можно решить только с помощью CSS, но нет полностью надежных исправлений CSS.

Решение, которое я имел в своем первоначальном ответе, состояло в том, чтобы добавить font-size: 0 к родительскому элементу, а затем объявить разумным font-size на детей.

http://jsfiddle.net/thirtydot/dGHFV/1361/

Это работает в последних версиях всех современных браузеров. Это работает в IE8. Он не работает в Safari 5, но работает в Safari 6. Safari 5 - практически мертвый браузер ( 0,33%, август 2015 г.).

Большинство возможных проблем с относительными размерами шрифтов не сложно исправить.

Тем не менее, хотя это разумное решение, если вам конкретно требуется только CSS-исправление, я не рекомендую, если вы свободны изменять свой HTML (как большинство из нас).


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

<p>
    <span>Foo</span><span>Bar</span>
</p>

Да это правильно. Я удаляю пробел в HTML между элементами inline-block.

Это просто. Это просто. Это работает везде. Это прагматичное решение.

Иногда вам нужно тщательно продумать, откуда появятся пробелы. Будет ли добавление другого элемента с помощью JavaScript добавлять пробелы? Нет, если вы делаете это правильно.

Давайте отправимся в волшебное путешествие по различным способам удаления пробелов с новым HTML:

<ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
</ul>
  • Вы можете сделать это, как я обычно делаю:

    <ul>
        <li>Item 1</li><li>Item 2</li><li>Item 3</li>
    </ul>
    

    http://jsfiddle.net/thirtydot/dGHFV/1362/

  • Или это:

    <ul>
        <li>Item 1</li
        ><li>Item 2</li
        ><li>Item 3</li>
    </ul>
    
  • Или используйте комментарии:

    <ul>
        <li>Item 1</li><!--
        --><li>Item 2</li><!--
        --><li>Item 3</li>
    </ul>
    
  • Или, вы можете даже полностью пропустить некоторые закрывающие теги (все браузеры хорошо с этим):

    <ul>
        <li>Item 1
        <li>Item 2
        <li>Item 3
    </ul>
    

Теперь, когда я ушел и утомил вас до смерти "тысячей различных способов удаления пробелов с помощью тридцати точек", надеюсь, вы забыли все о font-size: 0,


Кроме того, теперь вы можете использовать flexbox для достижения многих макетов, для которых вы, возможно, ранее использовали встроенный блок: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Для браузеров, соответствующих CSS3, есть white-space-collapsing:discard

см.: http://www.w3.org/TR/2010/WD-css3-text-20101005/

Хорошо, хотя я проголосовал как font-size: 0; и not implemented CSS3 feature ответы, после попытки я обнаружил, что ни один из них не является реальным решением.

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

Затем я решил удалить пробелы (это ответы об этом аргументе) между inline-block дивы от моего HTML источник (JSP), превратив это:

<div class="inlineBlock">
    I'm an inline-block div
</div>
<div class="inlineBlock">
    I'm an inline-block div
</div>

к этому

<div class="inlineBlock">
    I'm an inline-block div
</div><div class="inlineBlock">
    I'm an inline-block div
</div>

это некрасиво, но работает.

Но, подожди минутку... что если я создаю свои div внутри? Taglibs loops (Struts2, JSTL, так далее...)?

Например:

<s:iterator begin="0" end="6" status="ctrDay">
    <br/>
    <s:iterator begin="0" end="23" status="ctrHour">
        <s:push value="%{days[#ctrDay.index].hours[#ctrHour.index]}">
            <div class="inlineBlock>
                I'm an inline-block div in a matrix 
                (Do something here with the pushed object...)
           </div>
       </s:push>
    </s:iterator>
</s:iterator>

Абсолютно не мыслим, чтобы встроить все эти вещи, это будет означать,

<s:iterator begin="0" end="6" status="ctrDay">
    <br/>
    <s:iterator begin="0" end="23" status="ctrHour"><s:push value="%{days[#ctrDay.index].hours[#ctrHour.index]}"><div class="inlineBlock>
                I'm an inline-block div in a matrix             
                (Do something here with the pushed object...)
           </div></s:push></s:iterator>
</s:iterator>

это не читается, трудно поддерживать и понимать, и т.д...

Решение, которое я нашел:

используйте комментарии HTML, чтобы соединить конец одного div с началом следующего!

<s:iterator begin="0" end="6" status="ctrDay">
   <br/>
   <s:iterator begin="0" end="23" status="ctrHour"><!--
    --><s:push value="%{days[#ctrDay.index].hours[#ctrHour.index]}"><!--
        --><div class="inlineBlock>
                I'm an inline-block div in a matrix             
                (Do something here with the pushed object...)
           </div><!--
    --></s:push><!--
--></s:iterator>
</s:iterator>

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

И, как положительный побочный эффект, HTML source, хотя и наполненный пустыми комментариями, результат будет иметь правильный отступ;

давайте возьмем первый пример, imho это:

    <div class="inlineBlock">
        I'm an inline-block div
    </div><!--
 --><div class="inlineBlock">
        I'm an inline-block div
    </div>

лучше чем это

    <div class="inlineBlock">
         I'm an inline-block div
    </div><div class="inlineBlock">
         I'm an inline-block div
    </div>

Надеюсь, это поможет...

Добавлять display: flex; на родительский элемент. Вот решение с префиксом:

p {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
}
span {
  float: left;
  display: inline-block;
  width: 100px;
  background: blue;
  font-size: 30px;
  color: white;
  text-align: center;
}
<p>
  <span> Foo </span>
  <span> Bar </span>
</p>


Обновить

Упрощенная версия

p {
  display: flex;
}

span {
  width: 100px;
  background: tomato;
  font-size: 30px;
  color: white;
  text-align: center;
}
<p>
  <span> Foo </span>
  <span> Bar </span>
</p>

Все методы ликвидации космоса для display:inline-block противные хаки...

Используйте Flexbox

Это потрясающе, решает все эти встроенные блочные макеты, и по состоянию на 2017 год имеет 98% поддержку браузера (больше, если вы не заботитесь о старых IE).

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

<div>
    Element 1
</div><!--
--><div>
    Element 2
</div>

К сожалению, это 2015 и white-space-collapse до сих пор не реализовано.

А пока отдадим родительский элемент font-size: 0; и установить font-size на детей. Это должно сделать свое дело

Это тот же ответ, который я дал в отношении: Дисплей: Встроенный блок - Что это за пространство?

На самом деле существует действительно простой способ удаления пробелов из встроенного блока, который является простым и семантическим. Он называется нестандартным шрифтом с пробелами нулевой ширины, что позволяет свернуть пробел (добавленный браузером для встроенных элементов, когда они находятся на отдельных строках) на уровне шрифта с использованием очень маленького шрифта. После того, как вы объявите шрифт, вы просто измените font-family на контейнер и обратно на детей, и вуаля. Как это:

@font-face{ 
    font-family: 'NoSpace';
    src: url('../Fonts/zerowidthspaces.eot');
    src: url('../Fonts/zerowidthspaces.eot?#iefix') format('embedded-opentype'),
         url('../Fonts/zerowidthspaces.woff') format('woff'),
         url('../Fonts/zerowidthspaces.ttf') format('truetype'),
         url('../Fonts/zerowidthspaces.svg#NoSpace') format('svg');
}

body {
    font-face: 'OpenSans', sans-serif;
}

.inline-container {
    font-face: 'NoSpace';
}

.inline-container > * {
    display: inline-block;
    font-face: 'OpenSans', sans-serif;
}

Костюм по вкусу. Вот загрузка шрифта, который я только что приготовил в font-forge и конвертировал с помощью генератора веб-шрифтов FontSquirrel. У меня ушло всего 5 минут. CSS @font-face объявление включено: заархивированный шрифт пробела нулевой ширины. Он находится на Google Диске, поэтому вам нужно нажать "Файл"> "Загрузить", чтобы сохранить его на своем компьютере. Возможно, вам также потребуется изменить пути к шрифту, если вы скопируете объявление в ваш основной файл CSS.

Еще два варианта, основанные на текстовом модуле CSS уровня 3 (вместо white-space-collapsing:discard который был удален из спецификации проекта):

  • word-spacing: -100%;

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

  • word-spacing: -1ch;

Сокращает пробелы между словами на ширину цифры "0". В моноширинном шрифте он должен быть точно равен ширине символа пробела (и любого другого символа). Это работает в Firefox 10+, Chrome 27+ и почти работает в Internet Explorer 9+.

скрипка

Просто:

item {
  display: inline-block;
  margin-right: -0.25em;
}

Нет необходимости прикасаться к родительскому элементу.

Единственное условие здесь: размер шрифта элемента не должен быть определен (должен быть равен размеру шрифта родителя).

0.25em по умолчанию word-spacing

W3Schools - пространственное слово

Используйте flexbox и сделайте запасной вариант (из предложений выше) для старых браузеров:

ul {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
}

Хотя технически это не ответ на вопрос: "Как убрать пробел между элементами inline-block?"

Вы можете попробовать решение flexbox и применить приведенный ниже код, и место будет удалено.

p {
   display: flex;
   flex-direction: row;
}

Вы можете узнать больше об этом по этой ссылке: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Размер шрифта:0; может быть немного сложнее управлять...

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

.inline-block-wrapper>.inline-block-wrapper,
.inline-block-wrapper{letter-spacing: -4px;}
.inline-block-wrapper>*{letter-spacing: 0;display: inline-block;}

/* OR better shorter name...*/
.items>.items,
.items{letter-spacing: -4px;}
.items>*{letter-spacing: 0;display: inline-block;}

Тогда вы можете использовать его следующим образом...

<ul class="items">
   <li>Item 1</li>
   <li>Item 2</li>
   <li>Item 3</li>
</ul>

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

ОБЪЯСНЕНИЕ:

Это работает (возможно, -3px может быть лучше) именно так, как вы ожидаете, что это сработает.

  • Вы копируете и вставляете код (один раз)
  • тогда на вашем HTML просто используйте class="items" на родителя каждого inline-блока.

Вам НЕ нужно возвращаться к CSS и добавлять другое правило CSS для ваших новых встроенных блоков.

Решение двух вопросов одновременно.

Также обратите внимание на > (больше, чем знак) это означает, что */ все дочерние элементы должны быть встроены в блок.

http://jsfiddle.net/fD5u3/

ПРИМЕЧАНИЕ: я изменил, чтобы приспособить, чтобы наследовать межбуквенный интервал, когда у оболочки есть дочерняя оболочка.

Обычно мы используем такие элементы в разных строках, но в случае display:inline-block использование тегов в одной строке уберет пробел, но в другой строке - нет.

Пример с тегами в другой строке:

p span {
  display: inline-block;
  background: red;
}
<p>
  <span> Foo </span>
  <span> Bar </span>
</p>

Пример с тегами в одной строке

p span {
  display: inline-block;
  background: red;
}
<p>
  <span> Foo </span><span> Bar </span>
</p>


Другой эффективный метод - это работа CSS, которая использует font-size:0 на родительский элемент и дать font-size на дочерний элемент столько, сколько вы хотите.

p {
  font-size: 0;
}
p span {
  display: inline-block;
  background: red;
  font-size: 14px;
}
<p>
  <span> Foo </span>
  <span> Bar </span>
</p>

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

Я не совсем уверен, хотите ли вы сделать два синих пролета без пробела или хотите обработать другие пробелы, но если вы хотите устранить пробел:

span {
    display: inline-block;
    width: 100px;
    background: blue;
    font-size: 30px;
    color: white;
    text-align: center;

    float: left;
}

И сделано.

У меня была эта проблема прямо сейчас и из font-size:0; Я обнаружил, что в Internet Explorer 7 проблема остается, потому что Internet Explorer думает: "Размер шрифта 0?!?! WTF ты сумасшедший человек?" - Итак, в моем случае я сбросил CSS Эрика Мейера и с font-size:0.01em; У меня разница в 1 пиксель от Internet Explorer 7 до Firefox 9, поэтому я думаю, что это может быть решением.

p {
  display: flex;
}
span {
  float: left;
  display: inline-block;
  width: 100px;
  background: red;
  font-size: 30px;
  color: white;
}
<p>
  <span> hello </span>
  <span> world </span>
</p>

Самый простой ответ на этот вопрос - добавить.

CSS

float: left;

ссылка на кодовую ссылку: http://jsfiddle.net/dGHFV/3560/

Я думаю, что есть очень простой / старый метод для этого, который поддерживается всеми браузерами, даже IE 6/7. Мы могли бы просто установить letter-spacing на большое отрицательное значение в родительском и затем установите его обратно normal у дочерних элементов:

body { font-size: 24px }
span { border: 1px solid #b0b0c0; } /* show borders to see spacing */

.no-spacing { letter-spacing: -1em; } /* could be a large negative value */
.no-spacing > * { letter-spacing: normal; } /* => back to normal spacing */
<p style="color:red">Wrong (default spacing):</p>

<div class="">
  <span>Item-1</span>
  <span>Item-2</span>
  <span>Item-3</span>
</div>

<hr/>

<p style="color:green">Correct (no-spacing):</p>

<div class="no-spacing">
  <span>Item-1</span>
  <span>Item-2</span>
  <span>Item-3</span>
</div>

Я занимался этим недавно и вместо того, чтобы установить родителя font-size:0 затем установив дочерний элемент к разумному значению, я получил последовательные результаты, установив родительский контейнер letter-spacing:-.25em затем ребенок вернулся к letter-spacing:normal,

В другой ветке я видел упоминание комментатора о том, что font-size:0 не всегда идеален, потому что люди могут контролировать минимальный размер шрифта в своих браузерах, полностью отрицая возможность установки размера шрифта на ноль.

Использование ems работает независимо от того, установлен ли размер шрифта 100%, 15pt или 36px.

http://cdpn.io/dKIjo

С PHP скобками:

ul li {
  display: inline-block;
}
    <ul>
        <li>
            <div>first</div>
        </li><?
        ?><li>
            <div>first</div>
        </li><?
        ?><li>
            <div>first</div>
        </li>
    </ul>

Добавлять white-space: nowrap к элементу контейнера:

CSS:

* {
    box-sizing: border-box;
}
.row {
    vertical-align: top;
    white-space: nowrap;
}
.column{
    float: left;
    display: inline-block;
    width: 50% // Or whatever in your case
}

HTML:

<div class="row">
    <div class="column"> Some stuff</div>
    <div class="column">Some other stuff</div>
</div>

Вот Плункер.

Я собираюсь немного расширить ответ пользователя user5609829, так как считаю, что другие решения здесь слишком сложны / слишком много работы. Применяя margin-right: -4px для встроенных элементов блока удалит пробел и поддерживается всеми браузерами. Смотрите обновленную скрипку здесь. Для тех, кто заинтересован в использовании отрицательных полей, попробуйте прочитать это.

Я подумал, что добавлю что-то новое к этому вопросу, поскольку, хотя многие из предоставленных в настоящее время ответов более чем адекватны и актуальны, есть некоторые новые свойства CSS, которые могут обеспечить очень чистый результат, с полной поддержкой во всех браузерах и немного никаких "хаков". Это уходит отinline-block но он дает те же результаты, что и заданный вопрос.

Эти свойства CSS grid

CSS Grid широко поддерживается (CanIUse), за исключением IE, которому требуется только-ms- префикс, чтобы он работал.

CSS Grid также очень гибок и берет все хорошее из table, flex, а также inline-block элементы и объединяет их в одно место.

При создании gridвы можете указать промежутки между строками и столбцами. По умолчанию зазор уже установлен на0px но вы можете изменить это значение на любое другое.

Короче говоря, вот соответствующий рабочий пример:

body {
  background: lightblue;
  font-family: sans-serif;
}

.container {
  display: grid;
  grid-template-columns: 100px 100px;
  grid-column-gap: 0; /* Not needed but useful for example */
  grid-row-gap: 0; /* Not needed but useful for example */
}

.box {
  background: red;
}
.box:nth-child(even) {
  background: green;
}
<div class="container">
  <div class="box">
    Hello
  </div>
  <div class="box">
    Test
  </div>  
</div>

Я нашел чистое CSS-решение, которое очень хорошо работало для меня во всех браузерах:

span {
    display: table-cell;
}

Добавлять letter-spacing:-4px; на родителя p CSS и добавить letter-spacing:0px; на ваш span CSS.

span {
  display:inline-block;
  width:100px;
  background-color:palevioletred;
  vertical-align:bottom;
  letter-spacing:0px;
}

p {
  letter-spacing:-4px;
}
<p>
    <span> Foo </span>
    <span> Bar </span>
</p>

Есть много решений, таких как font-size:0, word-spacing, margin-left, letter-spacing и так далее.

Обычно я предпочитаю использовать letter-spacing так как

  1. Это нормально, когда мы назначаем значение, которое больше ширины дополнительного пространства (например, -1em).
  2. Тем не менее, это не будет хорошо с word-spacing а также margin-left когда мы устанавливаем большее значение, как -1em,
  3. С помощью font-size не удобно, когда мы пытаемся использовать em как font-size Блок.

Так, letter-spacing кажется лучшим выбором.

Тем не менее, я должен предупредить вас

когда вы используете letter-spacing ты лучше использовал -0.3em или же -0.31em не другие.

* {
  margin: 0;
  padding: 0;
}
a {
  text-decoration: none;
  color: inherit;
  cursor: auto;
}
.nav {
  width: 260px;
  height: 100px;
  background-color: pink;
  color: white;
  font-size: 20px;
  letter-spacing: -1em;
}
.nav__text {
  width: 90px;
  height: 40px;
  box-sizing: border-box;
  border: 1px solid black;
  line-height: 40px;
  background-color: yellowgreen;
  text-align: center;
  display: inline-block;
  letter-spacing: normal;
}
<nav class="nav">
    <span class="nav__text">nav1</span>
    <span class="nav__text">nav2</span>
    <span class="nav__text">nav3</span>
</nav>

Если вы используете Chrome(тестовая версия 66.0.3359.139) или Opera(тестовая версия 53.0.2907.99), то, что вы видите, может быть:

Если вы используете Firefox(60.0.2),IE10 или Edge, то, что вы видите, может быть:

Это интересно. Итак, я проверил mdn-letter-spacing и нашел это:

длина

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

Похоже, в этом причина.

Спецификация CSS Text Module Level 4 определяетtext-space-collapse свойство, которое позволяет контролировать способ обработки пустого пространства внутри и вокруг элемента.

Итак, что касается вашего примера, вам просто нужно написать это:

p {
  text-space-collapse: discard;
}

К сожалению, ни один браузер не реализует это свойство (по состоянию на сентябрь 2016 года), как указано в комментариях к ответу HBP.

Отрицательная маржа

Вы можете переместить элементы обратно на место с отрицательным полем в 4 пикселя (может потребоваться корректировка в зависимости от размера шрифта родителя). Очевидно, это проблематично в старых версиях IE (6 и 7), но если вам не нужны эти браузеры, по крайней мере, вы можете сохранить чистое форматирование кода.

span {
  display: inline-block;
  margin-right: -4px;
}

Используйте один из этих трюков

  1. Удалить пробелы
  2. Отрицательная маржа
  3. Пропустить закрывающий тег (HTML5 все равно)
  4. Установите размер шрифта равным нулю (пробел с нулевым размером шрифта равен... нулевой ширине)
  5. Используйте flexbox

Смотрите код ниже:

body {
  font-family: sans-serif;
  font-size: 16px;
}

ul {
  list-style: none
}

li {
  background: #000;
  display: inline-block;
  padding: 4px;
  color: #fff;
}

ul.white-space-fix li {
  margin-right: -4px;
}

ul.zero-size {
  font-size: 0px;
}

ul.zero-size li {
  font-size: 16px;
}

ul.flexbox {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
}
original...
<ul>
  <li>one</li>
  <li>two</li>
  <li>three</li>
</ul>

Funky code formatting...
<ul>
  <li>
   one</li><li>
   two</li><li>
   three</li>
</ul>

Adding html comments...
<ul>
  <li>one</li><!--
  --><li>two</li><!--
  --><li>three</li>
</ul>

CSS margin-right: -4px;
<ul class="white-space-fix">
  <li>one</li>
  <li>two</li>
  <li>three</li>
</ul>

Omitting the &lt;/li&gt;
<ul>
  <li>one
    <li>two
      <li>three
</ul>

fixed with font-size: 0
<br><br>
<ul class="zero-size">
  <li>one</li>
  <li>two</li>
  <li>three</li>
</ul>

<br> flexbox
<br>
<ul class="flexbox">
  <li>one</li>
  <li>two</li>
  <li>three</li>
</ul>

Другие вопросы по тегам