CSS nth-child выражение, чтобы избежать последней строки, содержащей не более 3 элементов

Я создаю списки, которые отображаются в столбцах по три, каждый <li> имеет border-bottom так:

x | x | x
---------    
x | x | x
---------      
z | z | z
---------  

<ul>
    <li>x</li><li>x</li><li>x</li>
    <li>x</li><li>x</li><li>x</li>
    <li>z</li><li>z</li><li>z</li>
</ul>

Я хочу создать выражение nth-child для удаления border-bottom в последней строке из трех, поэтому для приведенного выше примера будет:

ul li:nth-child(-n+6) {
    border-bottom:0;
}

Проблема

Однако, когда он немного усложняется, количество элементов в списке меняется, поэтому может возникнуть любой из следующих сценариев:

Сценарий 1

x | x | x
---------   
x | x | x
---------   
z |
---  

<ul>
    <li>x</li><li>x</li><li>x</li>
    <li>x</li><li>x</li><li>x</li>
    <li>z</li>
</ul>

Сценарий 2

x | x | x
---------   
x | x | x
---------   
z | z |
-------

<ul>
    <li>x</li><li>x</li><li>x</li>
    <li>x</li><li>x</li><li>x</li>
    <li>z</li><li>z</li>
</ul>

Сценарий 3

x | x | x
---------   
z | z |
-------

<ul>
    <li>x</li><li>x</li><li>x</li>
    <li>z</li><li>z</li>
</ul>

Заключение

Моя цель - всегда удалять border-bottom в последней строке (или в этом примере символ z), чтобы он не применял к нему стиль.

Идеальное решение будет:

ul {
    padding-bottom:-20px;
}

Но padding-bottom:-#px; не поддерживается в CSS.

Единственный другой способ, который я могу сделать для этого, - создать выражение nth-child для захвата только строк, содержащих 3, которые не являются последней строкой?

Думаю, может понадобиться какое-то деление на 3, чтобы найти сумму, чтобы применить ее тоже?

Ответ 1

До сих пор я создал селектор, который применяет стиль к последней строке

/* all the cells */
li {
   background: #ccc;
}

/* last row, doesn't matter how many cells */
li:nth-last-child(-n + 3):nth-child(3n + 1), /* first element of the last row */
li:nth-last-child(-n + 3):nth-child(3n + 1) ~ li /* all its following elements */
{
   /* reset the style, eg: */
   background: transparent;
}

Здесь вы можете увидеть живой пример http://jsbin.com/ufosox/1/edit

Конечно, это не поддерживает IE8 и меньше.

Ответ 2

Вместо nth-выражений возможно простое css-решение?

Установите border-bottom для каждого LI и переполнения: спрятано в UL. Затем переместите каждый LI 1px вниз, чтобы последняя строка была скрыта.

Пример: http://jsfiddle.net/willemvb/7uGRq/

Ответ 3

Так как я не вижу способа добиться желаемого результата только с использованием псевдоклассов nth-*, я попытался быть творческим: если ваши элементы списка имеют одинаковую высоту (например, предположим 30px), Таким образом, обходной путь с участием только css может быть выполнен таким образом

http://jsbin.com/ukubug/4/edit

CSS

ul { list-style: none;  
     margin: 3em 0 0 0; padding: 0;
     height: auto; overflow: hidden; 
     position : relative;
}

li { float: left; width: 30px; height: 30px; 
     position: relative; z-index: 1;
     text-align: center; line-height: 30px;  /* just to h/v centering */
}

li:nth-child(3n+1) { clear: left }


ul:before {
   position: absolute;
   z-index : 1;
   content : "";
   display : block;
   background : #f00;
   left    : 0;
   top     : -30px;  /* this is the height of your list-items */
   width   : 100%;
   height  : 100%;
}

Трюк заключается в том, чтобы применить цвет фона к псевдоэлементу ul:before, дать ему абсолютную позицию, а затем применить отрицательное верхнее смещение, равное высоте li.

overflow : hidden, примененный к ul, будет работать как метод очистки, так и разрезать красный слой, расположенный за пределами его родительской границы. В то же время вам нужно также позиционировать элементы li, чтобы они могли перекрываться ul:before.

Обратите внимание, что если у вас есть менее 4 элементов li, вы не увидите никакого эффекта выделения (так как ваша первая строка также является вашей последней строкой): если вам нужно выделить всегда по крайней мере одну строку (частично заполненную или не) просто примените

min-height : 60px;  /* double height of a li element */

до ul:before.

надеюсь, что это может быть полезно.


В качестве окончательного рассмотрения отметим также, что это само решение (*)

  • должен работать нормально даже на IE8, в то время как решение, основанное на псевдоклассах nth-*, не будет работать на этом pseudobrowser
  • он легко масштабируется, если вы переключаетесь на макет столбца 2/4/5/6/...

(*) это требует другого способа получить a clear: left на элементах 3n+1 li, конечно:)

Ответ 4

Я не знаю, есть ли у вас доступ к самому HTML-коду, но если вы это сделаете, моим идеальным решением было бы добавить еще один html div ПОСЛЕ ul, дать цвет фона белого цвета, высоту 30 пикселей и top или margin-top -30px (или что-то, что необходимо, чтобы скрыть последний кусок ul)

<ul>...</ul>
<div style="background-color: #fff; height: 30px; margin-top: -30px">&nbsp;</div>

другое примечание, вы попробовали дополнить дно, но вы попробовали margin-bottom: -20px?

Ответ 5

Я предлагаю вам применить стиль ко всем вашим li, а затем выполнить определенное правило для последнего:

ul li:last-child {
    background-color:#FF0;
}

Обратите внимание, что: last-child несовместим с IE LTE 8 (http://www.quirksmode.org/css/contents.html)