CSS Alternate Rows — некоторые строки скрыты

Я пытаюсь оформить таблицу так, чтобы каждая строка была разного цвета (нечетная/четная). У меня есть следующий CSS:

#woo tr:nth-child(even) td {
    background-color: #f0f9ff;
}

#woo tr:nth-child(odd) td {
    background-color: white;
}

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


person Andy    schedule 02.06.2011    source источник
comment
Я скрываю строки с display: none.   -  person Andy    schedule 04.06.2011
comment
просто быстро: действительно ли необходимо иметь тысячу строк? Вы не можете использовать пагинацию?   -  person Ionuț Staicu    schedule 04.06.2011


Ответы (6)


Если вы используете jQuery, вы можете использовать одну из его функций, например .filter(), чтобы выбрать только видимые элементы. Но ключевым здесь является селектор CSS :visible.

Например (см. jsfiddle):

jQuery('tr:visible:odd').css({'background-color': 'red'});
jQuery('tr:visible:even').css({'background-color': 'yellow'});
person Tadeck    schedule 02.06.2011
comment
На самом деле я пробовал это, но по мере того, как моя таблица росла в размерах, поскольку она всегда добавлялась, это, казалось, приводило Firefox в тупик, поэтому я искал чисто CSS-исправление, чтобы посмотреть, смогу ли я облегчить бремя JS на моей странице. - person Andy; 04.06.2011
comment
Как я уже сказал, ключом здесь является селектор CSS, но он, вероятно, не работает в устаревших браузерах, таких как старые версии IE (пожалуйста, проверьте, работает ли он в браузерах, которые вы хотите поддерживать). Если чистое решение, основанное только на CSS, вас не удовлетворяет, остается только добавить определенные классы с помощью JS (хотя, возможно, изменив мое решение). - person Tadeck; 04.06.2011

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

Row 1
Row 2
Row 3 (hidden)
Padding (hidden)
Row 4
Row 5

Если это действительно хорошее решение, это сильно зависит от вашего текущего кода, например. как вы создаете таблицу и как строки скрыты.

Но если ваши таблицы огромны и большие фрагменты последовательных строк скрыты, это будет работать намного лучше, чем решение Javascript/jQuery.

person Daniel Rikowski    schedule 10.10.2013
comment
Просто гениально!! - person Moti Korets; 11.06.2019

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

Фоновое изображение в кодировке base64 ниже представляет собой изображение размером 1x50 с верхними 25 пикселями в качестве одного цвета и нижними 25 пикселями в качестве альтернативного цвета.

table {
  border-collapse: collapse;
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAyCAIAAAASmSbdAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wQbATAssXhCIwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAYSURBVAjXY/j8/joTAwMDTfGXDzdpbQcATuQF2Ze0VigAAAAASUVORK5CYII=);
}
  
td {
   padding: 2px 4px;
   height: 21px;
}
<table>
    <tbody>
        <tr style="display: table-row;">
            <td>ANIMAL!!</td>
        </tr>
        <tr style="display: table-row;">
            <td>Beaker</td>
        </tr>
        <tr style="display: none;">
            <td>Bunsen Honeydew, Ph.D.</td>
        </tr>
        <tr style="display: table-row;">
            <td>Camilla the Chicken</td>
        </tr>
        <tr style="display: table-row;">
            <td>Dr. Julius Strangepork</td>
        </tr>
        <tr style="display: none;">
            <td>Dr. Teeth</td>
        </tr>
        <tr style="display: none;">
            <td>Floyd Pepper</td>
        </tr>
        <tr style="display: none;">
            <td>Gonzo</td>
        </tr>
        <tr style="display: table-row;">
            <td>Janice</td>
        </tr>
        <tr style="display: none;">
            <td>Miss Piggy</td>
        </tr>
        <tr style="display: none;">
            <td>Rizzo</td>
        </tr>
        <tr style="display: none;">
            <td>Robin the Frog</td>
        </tr>
        <tr style="display: table-row;">
            <td>Sam the Eagle</td>
        </tr>
        <tr style="display: table-row;">
            <td>Statler</td>
        </tr>
        <tr style="display: none;">
            <td>The Swedish Chef</td>
        </tr>
        <tr style="display: table-row;">
            <td>Waldorf</td>
        </tr>
        <tr style="display: none;">
            <td>Zoot</td>
        </tr>
    </tbody>
</table>

person Jeff Seifert    schedule 27.04.2015

Я понимаю, что это очень поздно, но сегодня я столкнулся с той же проблемой и придумал чистое решение CSS, используя формулу nth-child. Я не знаю, соответствует ли это вашему конкретному сценарию, но если все остальные строки скрыты, но вам все еще нужно, чтобы видимые строки были чередующимися цветами, это прекрасно работает. Селектор CSS выглядит так:

tr:nth-child(4n - 1) { background-color: grey; }

Вот скрипка, показывающая ее в действии.

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

person lhan    schedule 06.03.2015
comment
Этот ответ является лучшим в моем случае. Некоторые строки могут стать видимыми, но я не хочу, чтобы они включались в изменение цвета фона, поэтому для меня это работает лучше, чем решение jquery: visible. Спасибо! - person yennefer; 05.01.2016
comment
Это работает только в том случае, если каждая вторая строка скрыта, но если вы используете фильтр, который скрывает случайные строки, этот код больше не работает. - person narfie; 28.05.2019
comment
@narfie - вот почему я указал если каждая вторая строка скрыта и предположил, что это может не соответствовать точному сценарию. Не уверен, что отрицательный голос заслуживает, но ¯_(ツ)_/¯ - person lhan; 31.05.2019

Это сложная проблема, я только что провел некоторое время, играя с селекторами CSS2 и 3, и я не уверен, что мы уже там. Что-то вроде этого должно быть возможно, но не работает:

tr td {background-color:white;}
tr td:not([style="display:none"]):nth-of-type(even) {
    background-color:#f0f9ff;
}

<tr><td>1</td></tr>
<tr><td style="display:none">2</td></tr>
<tr><td>3</td></tr>

Кажется, вы застряли с расширением jQuery :visible (а не собственным CSS), но если оно работает медленно, обязательно разбейте строки на страницы, как говорит @Ionut.

person Karl Andrew    schedule 04.06.2011
comment
Хорошая идея, но она не работает, потому что nth-of-type не учитывает никакие другие селекторы, а только тип элемента. (На языке XML это будет имя узла). Возможно, однажды у нас будет селектор nth-of-selector-match :) - person Daniel Rikowski; 10.10.2013

Этот вопрос может быть старым, но когда я искал решение этой проблемы, я пришел сюда и вдохновился ответом Джеффа Зайферта. Я использовал фоновое изображение с повторяющимся линейным градиентом, чтобы иметь решение, основанное исключительно на css:

tbody {
    background-image: repeating-linear-gradient(grey 0 2em, white 2em 4em);
}
tr {
    height: 2em;
}

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

EDIT: это работает, только если все строки имеют одинаковую высоту. К сожалению, max-height не работает для строк таблицы. У меня есть два полусырых решения для этого:

  1. Предотвратите перенос текста, применив tr{white-space: nowrap;}. По-прежнему необходимо соблюдать осторожность для нетекстовых элементов, переполнение также может стать проблемой.

  2. Оберните содержимое <tr> другим элементом, например <div>, и примените div{max-height:2em;}. Это требует изменений в HTML, а также обработки переполнения.

person micha    schedule 18.07.2020