There is now a CSS Nesting Module in the CSS specification. The module is currently a Working Draft and CSS nesting is supported in all major browsers.
The syntax looks like this:
table.colortable {
& td {
text-align:center;
&.c { text-transform:uppercase }
&:first-child, &:first-child + td { border:1px solid black }
}
& th {
text-align:center;
background:black;
color:white;
}
}
.foo {
color: red;
@nest & > .bar {
color: blue;
}
}
.foo {
color: red;
@nest .parent & {
color: blue;
}
}
Answer from etoxin on Stack OverflowCSS nesting: use with caution
css selectors - Nesting CSS classes - Stack Overflow
Begginer question: nested css or classes
nesting inside css :not() selectors - Stack Overflow
Videos
There is now a CSS Nesting Module in the CSS specification. The module is currently a Working Draft and CSS nesting is supported in all major browsers.
The syntax looks like this:
table.colortable {
& td {
text-align:center;
&.c { text-transform:uppercase }
&:first-child, &:first-child + td { border:1px solid black }
}
& th {
text-align:center;
background:black;
color:white;
}
}
.foo {
color: red;
@nest & > .bar {
color: blue;
}
}
.foo {
color: red;
@nest .parent & {
color: blue;
}
}
Not possible with vanilla CSS. However you can use something like:
- Sass
Sass makes CSS fun again. Sass is an extension of CSS3, adding nested rules, variables, mixins, selector inheritance, and more. It’s translated to well-formatted, standard CSS using the command line tool or a web-framework plugin.
Or
- Less
Rather than constructing long selector names to specify inheritance, in Less you can simply nest selectors inside other selectors. This makes inheritance clear and style sheets shorter.
Example:
#header {
color: red;
a {
font-weight: bold;
text-decoration: none;
}
}
:not() only accepts one simple selector at a time; this is mentioned in the Selectors 3 spec:
The negation pseudo-class,
:not(X), is a functional notation taking a simple selector (excluding the negation pseudo-class itself) as an argument. It represents an element that is not represented by its argument.
The simple selectors in your example would be the two div tokens that you have. Other simple selectors include class selectors, ID selectors, attribute selectors and pseudo-classes. It does not accept more than one simple selector, nor does it accept combinators like > or space.
Depending on which elements you're trying to select exactly, there may not be a way to exclude div > div:
If you only want to select elements that are children of a
div, that are themselves notdiv, use this instead:div > :not(div)If you only want to select
divelements whose parent element is not adiv, use this instead::not(div) > div
If you want to use this negation by itself, selecting all other elements, then there isn't a way using just a selector.
The only other viable workaround in CSS that I can think of is to apply styles to the elements you want without the :not() expression, then undo them for div > div. This works for any set of elements you're trying to target; the disadvantage is that not all properties can be easily reset.
Alternatively, if you're using jQuery, which does support :not(div > div) unlike the CSS version, you can place the selector in a script and, for instance, have jQuery apply a class name to those elements then target that class in your CSS.
It should work now thanks to Selectors Level 4 which allows :not() to take a list of complex selectors.
You can now also nest :not()... like :not(:not()) which wasn't allowed in Selectors Level 3. Not sure why you'd want to do that but you can.
Oh - nesting cannot be done
The :has() pseudo-class cannot be nested within another :has().
https://developer.mozilla.org/en-US/docs/Web/CSS/:has
#outer-div:has(> .inner-div + .inner-div) works to select "a parent with a child who is a sibling" which is sufficient
how best to select a parent with 2 specific children in it?
Here is a solution which can realize the effect but does not need nested relative selectors:
.outer-div{
margin: 10px;
border: 1px solid;
display: inline-block;
}
.outer-div:has(.inner-div+.inner-div){
color: red;
}
<div class="outer-div">
<div class="inner-div">1</div>
<div class="inner-div">1</div>
</div>
<div class="outer-div">
<div class="inner-div">2</div>
<div class="inner-div1">2</div>
</div>
<div class="outer-div">
<div class="inner-div">3</div>
</div>
And here is the pen: https://codepen.io/lerner-zhang/pen/OJdzyPp
And hopefully this answer would be helpful to you: https://stackoverflow.com/a/77499244/3552975
Both are completely acceptable to use and the answer depends on your specific solution. For instance if you have other areas where you are sharing common properties that are defined by that class you'd want to keep it as general as possible. If for instance you have a navigation and the links in that area share some common elements those could be defined by a.link
Then in your nested html, you might do something like
.someclass a.link {font-size:8px} to make that text smaller.
Here is an article that discusses how the specificity works: http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/
Both are perfectly valid, and which one you use depends on what you want to do.
If you are creating a generic class that you want to be able to use throughout your entire site regardless of element and where the element is, you should only use .class. A good example for this is something like .icon which you may want to use on links, list items, headings etc. And you want to be able to use them everywhere.
If you're creating a class that is specific to/only works on one certain type element, it's best to use the element in the selector as well. An example of this would be a bullet list you want to display on one line, since this class requires the HTML to be a <ul> you should specify it in the CSS as well; ul.inline. This way you can use the "inline" class name for other elements as well, without the styling affecting both.
If you're only using the class in order to select the element but it shouldn't have any generic styling you should be specific. For example, you may want the first paragraph in your #blog-post element to be larger, then you should specify both #blog-post and the class; #blog-post p.first (note that these types of classes are rarely needed anymore thanks to advanced selectors like :first-of-type, h2 + p etc).
Saying that ".link is the best, a.link is second best and a long selector is bad" is just wrong. It all depends on the situation.