Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

When table rows use the HTML hidden attribute, plain tr:nth-child(even) still counts them. Use tr:nth-child(even of :not([hidden])) instead: its of clause filters hidden rows out before counting, so the visible rows keep alternating stripes.

Why hidden rows shift the stripes

:nth-child() calculates an element’s position among its element siblings, starting at 1. The keyword even selects positions 2, 4, 6, and so on. In tr:nth-child(even), the tr type selector limits which elements receive the style, but it does not limit which siblings count toward those positions.

A tr with the hidden attribute remains in the sibling list. Its position can therefore shift the parity of later rows, even though that row is not displayed. The visible stripes may then look uneven or appear to merge.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use the of clause to count only visible rows

tr:nth-child(even of :not([hidden])) {
  background: #eee;
}

The selector inside of defines the sibling set used for counting. Here, :not([hidden]) includes rows without the hidden attribute; even then selects every second row in that filtered set. The W3C Selectors Level 4 specification gives this approach for zebra-striping rows hidden with the HTML attribute.

#1 Best Overall
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Why adding :not([hidden]) outside does not fix counting

These selectors look similar, but only the third filters the set before positions are calculated:

/* Counts all child elements, then matches even-positioned tr elements. */
tr:nth-child(even) { /* ... */ }

/* Still counts all child elements; then excludes hidden rows from styling. */
tr:not([hidden]):nth-child(even) { /* ... */ }

/* Counts only siblings that are not hidden, then matches even rows. */
tr:nth-child(even of :not([hidden])) { /* ... */ }

In the second selector, :not([hidden]) is an additional match condition. It does not change the sibling list used by :nth-child(even). The of clause is what changes that list.

Match the selector to how your site hides rows

The example excludes rows carrying the hidden attribute; it does not detect every way a row could be concealed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Rows removed from the DOM: Removed rows are no longer siblings, so they cannot affect the index.
  • Rows hidden with the HTML attribute: The example selector excludes them.
  • Rows hidden some other way: If CSS conceals a row without setting hidden, :not([hidden]) will still count it. Filter on the actual state used by your markup or change the markup so the selector can identify hidden rows.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Check browser support for your targets

MDN describes :nth-child() and its of syntax as widely available, while noting that support for some parts may vary. If your project must support older browsers, check the of syntax against its target-browser requirements before relying on it.

Rank #3
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.