0

Consider the following HTML - a classic grid system:

<div class="container">
    <div>
        <div class="grid">
            <div>
                <ul class="row">
                    <li class="grid"></li>
                </ul>
            </div>
        </div>
    </div>
</div>

A section always starts with a .container

The first .grid in the hierarchy is not preceeded by a .row

The second, third... .grid elements are always divided by a .row.

A .grid is always a descendant of a container, but not guaranteed to be the first direct descendant.

A .row is always a descendant of a .grid, but not guaranteed to be the first direct descendant.

A child .grid is always a descendant of a .row, but not guaranteed to be the first direct descendant.

I want to find the first .grid element below a .container (the first in the branch). If there are multiple branches I want to select all of them. The .grid element is never preceeded by a .row - any advice?

GreyRoofPigeon
  • 17,833
  • 4
  • 36
  • 59
dotnetnoob
  • 10,783
  • 20
  • 57
  • 103
  • 2
    Are you limited to use only these 3 classes? I mean, if you had something like `.child-grid` for child grids it would be much easier. – Artyom Neustroev Feb 16 '15 at 09:53

3 Answers3

2

Since a .grid may occur anywhere between it and its container or its ancestor .row, you will not be able to do this with just a single selector. Using > combinators requires knowing in advance where exactly each level of .grid is nested and assuming it will not change, and :not() does not allow combinators so you couldn't do something like .container .grid:not(.row .grid) (unless you use jQuery).

Instead, you will need to style all .grid elements and revert the styles for any nested ones:

.container .grid {
    /* Styles */
}

.container .row .grid {
    /* Revert above styles */
}
Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
1
.container > .grid,
.container > :not(.row) > .grid {}

The :not() has acceptable browser support (IE > 8, all others).

Add depth as you need.

Boldewyn
  • 81,211
  • 44
  • 156
  • 212
  • Whilst I understand the answer, I'm a little confused as to the use of the > operator - row and grid elements are not guaranteed to be immediate descendants. – dotnetnoob Feb 16 '15 at 09:57
  • 1
    @dotnetnoob: `.container > :not(.row) > .grid` represents a grid that is a grandchild of container. The answer is saying to add as many levels of `> :not(.row)` as needed to account for all possible depths, but this only works if you know in advance how many cases there are and you don't mind accounting for every single one of them. – BoltClock Feb 16 '15 at 10:00
  • I think this would be too tricky to manage in its current form. – dotnetnoob Feb 16 '15 at 10:02
  • Is it tricky? Yes. Is it fragile? Hell, yes! Just another layer of `
    `s, and the selector doesn't match anymore. [Do you want the impossible?](https://en.wikiquote.org/wiki/Star_Wars_Episode_V:_The_Empire_Strikes_Back) Well, CSS is (right now) not suited for arbitrary path traversal. You could do it with JavaScript, putting the logic you need there, and then style it. Or, even better, take Artyom's comment to your question and add classes to make things addressable.
    – Boldewyn Feb 16 '15 at 10:34
0

is this what you mean?

<style>
.container li.grid:first-child {
    background-color: yellow;
}
</style>
saimiris_devel
  • 667
  • 1
  • 6
  • 19
  • No - if I understand correctly that will return the first grid child in the li element - I don't know which level the element exists. – dotnetnoob Feb 16 '15 at 09:55