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

Равномерно распределенная высота дочерних элементов с CSS

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

Вот как это должно выглядеть с четырьмя цветами, высота списка 90 пикселей и толстая рамка вокруг:

Firefox

Изображение выше показано в Firefox 3.6.13 из следующего источника:

<ul style="height: 90px; border: 5px solid black; padding: 0;">
    <li style="height: 25%; background: red;">
    <li style="height: 25%; background: blue;">
    <li style="height: 25%; background: yellow;">
    <li style="height: 25%; background: green;">
</ul>

Все в порядке. Список действительно 90 пикселей высотой - внутри границ - и каждый цвет получает (по-видимому) равную долю этого пространства. Теперь давайте покажем один и тот же HTML/CSS в Safari или Chrome:

Chrome

Обратите внимание на узкий белый ряд между зеленой строкой и границей. Существует довольно простое объяснение того, что мы видим здесь: 0.25 × 90 = 22.5

WebKit в Safari и Chrome не очень любят нецелые высоты пикселей и делят десятичные числа. С четырьмя рядами высоты 22 мы получаем 2 пикселя ничто в нижней части списка: 90 - 4 × 22 = 2

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

Я знаю, как это решить, вычисляя и устанавливая высоту целочисленного значения для каждой строки onload с помощью Javascript, и я опубликую это решение, если ничего не появится. Однако я предпочел бы чисто основанное на CSS решение проблемы. Можете ли вы подумать об этом?

4b9b3361

Ответ 1

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

script ожидает, что в точке ввода будут объявлены две переменные: list должен указывать на элемент DOM контейнера (например, <ul>) и items на коллекцию элементов (например, <li>) в этом списке.

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

var spaceRemaining = list.clientHeight;
var itemsRemaining = items.length;

while (itemsRemaining > 0) {
    var itemHeight = Math.round(spaceRemaining / itemsRemaining);
    items[itemsRemaining - 1].style.height = itemHeight;
    spaceRemaining -= itemHeight;
    itemsRemaining -= 1;
}

Для тех, кто предпочитает лаконичность по читаемости, здесь более короткая версия того же самого script:

for (var space = list.clientHeight, i = items.length; i; i--) {
    space -= items[i-1].style.height = Math.round(space / i);
}

Ответ 2

Попробуйте удалить все концы между тегами <li>. Напр.

<ul><li></li><li></li></ul>

Иногда это была проблема, но в вашей ситуации я не уверен, что это поможет;) Просто попробуйте;)