Подтвердить что ты не робот

3 встроенных блока div с ровной 33% шириной, не подходящей в родительском

Это обычная проблема, но я не могу понять, почему это происходит.

У меня есть родительский div и внутри div. У меня есть 3 divs с шириной, установленной на 33% (точно, не 33.3%!) и display: inline-block.

В Chrome это работает хорошо, но в Mozilla и Opera это не так (я еще не тестировал его в IE). Я думал, что проблема может быть в браузерах алгоритмов, используемых для вычисления размера пикселей из процентов. Но когда я проверил метрики DOM, я обнаружил, что ширина родительского элемента равна 864px, а у ребенка 285px (это верно: 864 *.33 = 285.12). Но почему он не подходит для родителей? 285 * 3 = 855, что на 9px меньше родительской ширины!

О, да, отступы, поля и границы для всех div, установленных в 0 и DOM, подтверждают это.

4b9b3361

Ответ 1

Пробел в исходном коде HTML

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

one
two
<img src="three.png"/>
<span style="display: inline-block;">four<span>

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

Удаление дополнительного пространства

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

Например, если у вас есть ul с 3 плавающими тегами li:

<-- No space, tabs, or line breaks between </li> and <li> -->
<ul>
    <li>...</li><li>...</li><li>...</li>   
</ul>

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

Если другой программист приходит позже и решает поместить каждый тег li в отдельную строку в исходном коде (не подозревая, почему теги находились в одной строке или, возможно, запускали его через HTML Tidy и даже не имели шанс заметить любые связанные комментарии HTML), внезапно на веб-сайте есть ошибка форматирования, которую может быть трудно идентифицировать.

Рассмотрим вместо этого плавающие элементы

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

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

Краткое резюме других решений

  • Поместите тег закрытия в ту же строку, что и следующий открытый тег, без пробелов между ними.
  • Используйте комментарии HTML, чтобы заполнить все пробелы между тегом close и следующим открытым тегом (как предлагал @Arbel).
  • Добавьте отрицательный левый край к каждому элементу (обычно -3px или -4px, на основе размера шрифта). Я не рекомендую этот подход.
  • Задайте font-size для элемента контейнера 0 или 0.01em. Это не работает в Safari 5 (не уверен в более поздних версиях), и это может повлиять на сайты адаптивного дизайна или на любой сайт, на котором используется font-size, кроме px.
  • Удалите только текстовые узлы только для пробелов из контейнера, используя JavaScript или jQuery. Это не работает в IE8 и ранее, поскольку текстовые узлы не создаются в этих браузерах, когда между элементами есть только пробел, хотя между элементами все еще добавлено пространство.
  • Установите letter-spacing и word-spacing для контейнера (как предлагал @PhillipWills). Дополнительная информация. Для этого требуется стандартизация размеров em на веб-сайте, что может быть не приемлемым вариантом для всех веб-сайтов.
  • Добавьте text-space-collapse: discard; в контейнер (ранее называемый white-space-collapse). К сожалению, этот стиль CSS3 пока не поддерживается никакими браузерами, и стандарт не был полностью определен.

Ответ 2

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

Например, в вашем коде это решит проблему, она даже будет работать с 33,3% вместо 33%:

.parent {
    width: 100%;
 }
.child{
    display: inline-block;
    width: 33.3%;
}

/\

<div class="parent">
       <div class="child">bla-bla1</div><!-- 
    --><div class="child">bla-bla2</div><!-- 
    --><div class="child">bla-bla3</div>
</div>

Ответ 3

Между внутренними divs добавляется пробел. Для исправления этой проблемы существует некоторое voodoo CSS:

div {
    letter-spacing: -.31em;
    word-spacing: -.43em;
}
div div {
    letter-spacing: normal;
    word-spacing: normal;
}

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

Ответ 4

Добавить float:left;

.parent{
    width: 100%
}
.child{
    float:left;
    display: inline-block;
    width: 33%

}

http://jsfiddle.net/H6Whc/1/

Ответ 5

Кто-нибудь попробовал display: table? Если это не очень хорошая идея, почему бы и нет? Это работает во всех современных браузерах, и я тестировал его на IE9.

.parent{  
    display: table;
    width: 100%;
}
.containers {
    box-sizing: border-box;
    border: 1px solid #000;
    height: 50px;
    width: 33.3%;
    display: table-cell;
}

Ответ 6

Это упоминается рядом комментариев и @Avin, но удаление display: inline-block и замена его на float: left работает.

.parent{
    width: 100%
}
.child{
    float:left;
    width: 33%
}

Ответ 7

Это обычная проблема, но ее можно легко отсортировать, назначив свойство display: table CSS родительскому div.