How to reuse CSS selector? - css

I have the following CSS:
.foo .bar {
background: red;
}
Which works fine for the following HTML:
<div class="foo">
<div class="bar">I have a red background</div>
</div>
But I can't seem to find a way to reuse the CSS definition when I'm not in a parent/child relationship. For example, how could I apply the same CSS to the following DIV:
<div class="???">I want a red background!</div>

You can add additional selector with comma (,) as specified in W3C selectors grouping
.foo .bar, .foobar {
background: red;
}
this would work in both
<div class="foo">
<div class="bar">I have a red background</div>
</div>
and
<div class="foobar">I want a red background!</div>

You can use a comma to indicate multiple selectors that a CSS rule should apply to
.foo .bar, .??? {
background: red;
}

Use a comma separated list of selectors in the definition:
.foo .bar, .otherSelector, #someID{
background: red;
}

.foo .bar, .redback {
background: red;
}
will do a magic with
<div class="redback">I want a red background!</div>
or get rid of hierarchy and use only
.bar {
background: red;
}
which will work both cases

Try
.foo .bar, .foobar {
background: red;
}
with
<div class="foo">
<div class="bar">I have a red background</div>
</div>
<div class="foobar">I want a red background!</div>

The ".foo .bar" CSS definition is written expressly for a parent-child (more accurately ancestor-decendent) relationship.
You could write the CSS like this:
.alternate-background {
background: red;
}
and the HTML like this:
<div>
<div class="alternate-background">I have a red background</div>
</div>
which would allow you also to use this:
<div class="alternate-background">I want a red background!</div>

Related

CSS is applied from the last object in CSS file instead of closest parent

I am building a web site that is basically made out of sections + rows + columns and to each element you can apply a color scheme.
If the color scheme is applied to the section, all the rows and columns within it will have the same color scheme, however, sometimes I want to add a color scheme to a single column to differentiate it, but in some cases the parent section color scheme css is placed AFTER the color scheme css for the column (in the css file), and then it applies the colors for the section instead of the columns.
Here is the code (simplified for the sake of example).
I could get around it in specific cases, using !important, but I am looking for a global solution.
CSS:
/* Grey */
.color-scheme-grey button {
background-color: #666666;
color: #ffffff;
}
/* Blue */
.color-scheme-blue button {
background-color: blue;
color: #ffffff;
}
HTML:
<div class="section color-scheme-blue">
<div class="row">
<div class="column color-scheme-grey">
<button>I am blue, but I wish I was grey!</button>
</div>
</div>
</div>
Thanks!
This is expected behaviour as a direct result of Cascade Precedence.
If two rules carry the same weight or specificity the rule declared last always wins and over-qualifies the other.
Use more Specificity
Consider declaring another element or class selector in the range of the contextual selectors already specified.
Example:
Added element selector (div) for more specificity...
div.color-scheme-grey button { ... }
Added a class selector (.section) for more specificity...
.section .color-scheme-grey button { ... }
Code Snippet Demonstrations:
1. Additional Class Selector:
/* Grey */
.section .color-scheme-grey button {
background-color: #666666;
color: #ffffff;
}
/* Blue */
.color-scheme-blue button {
background-color: blue;
color: #ffffff;
}
<div class="section color-scheme-blue">
<div class="row">
<div class="column color-scheme-grey">
<button>I am blue, but I wish I was grey!</button>
</div>
</div>
</div>
2. Additional Element Selector:
/* Grey */
div.color-scheme-grey button {
background-color: #666666;
color: #ffffff;
}
/* Blue */
.color-scheme-blue button {
background-color: blue;
color: #ffffff;
}
<div class="section color-scheme-blue">
<div class="row">
<div class="column color-scheme-grey">
<button>I am blue, but I wish I was grey!</button>
</div>
</div>
</div>
For Further Information regarding CSS Specificity:
Specificity - CSS | MDN
Specifics on CSS Specificity | CSS Tricks
Apply your styles from the parent like below.
.section .color-scheme-grey button {
background-color: #666666;
color: #ffffff;
}
DEMO
You could increase the specificity of the rules to counteract the order of the files:
/* Grey */
.color-scheme-grey button {
background-color: #666666;
color: #ffffff;
}
/* Blue */
.color-scheme-blue button {
background-color: blue;
color: #ffffff;
}
.color-scheme-blue .color-scheme-grey button {
background-color: #666666;
}
You need to be careful with this, though, as it can very quickly get out of hand with all the combinations!
Better would be to organise a set of formatting that applies to rows/sections and, separately, columns, and organise them appropriately in a file (sections first).

Select div by contains with css

I have a simple markup and I would like to select a div by it's content. Here is my code...
<div class="parent">
<h4>Child of parent</h4>
<div>
<div>I'm red!</div>
<h4>I'm red's sister</h4>
<div>I'm blue!</div>
<h4>I'm blue's brother</h4>
</div>
</div>
and selecting <div>I'm red!</div> with the following CSS...
div:contains("I'm red!") {
color: red;
}
since contains() is deprecated or never got implemented, I can do the following...
.parent div:nth-child(1) {
color: red;
}
.parent dh4:nth-child(2) {
color: red;
}
to target just the first two elements, and it worked, but I would like to know if it is a way I can target just the first two element which happened to be <div> and <h4> in one CSS line of code? I need to do this without javascript. Eventually I need to target just 3rd and 4th.
Yes. Use :nth-child(-n+2).
For the 3rd and 4th you can use :nth-child(n+3):nth-child(-n+4) or just :nth-child(-n+4) and let specificity fix it for you.
The logic is easy:
:nth-child(-n+a) selects the a-th element and its previous siblings
:nth-child(n+a) selects the a-th element and its following siblings
:nth-child(n+a):nth-child(-n+b) selects the a-th and b-th elements, and the siblings in-between.
.parent > div > :nth-child(-n+4) {
color: blue;
}
.parent > div > :nth-child(-n+2) {
color: red;
}
<div class="parent">
<h4>Child of parent</h4>
<div>
<div>I'm red!</div>
<h4>I'm red's sister</h4>
<div>I'm blue!</div>
<h4>I'm blue's brother</h4>
</div>
</div>
I don't think I understand your question. You can do that to have it on one line anyway.
.parent div:nth-child(1), .parent dh4:nth-child(2) {color: red;}
or you could apply a red class on the first two divs and do :
.red{color:red}

Styling adjacent groups of like classes as a block via CSS? Obvious or impossible?

I have an interesting problem, consider this HTML:
<div class="foo">Hello</div>
<div class="foo">World</div>
<div class="bar">Hotel</div>
<div class="bar">Romeo</div>
<div class="bar">Foxtrot</div>
<div class="foo">Ford</div>
<div class="foo">Prefect</div>
This content is dynamically generated and I never know when the class is going to flip. Is there a pure CSS way of styling groups of elements of a class? For example, I want each adjacent group of class "foo" to be bold and have a specific margin while each adjacent group of class "bar" I want to be red in color.
**Hello**
**World**
Hotel
Romeo
Foxtrot
**Ford**
**Prefect**
Help me stackoverflow, you're my only hope!
How about:
.foo + .bar,
.bar + .foo{
margin-top:10px;
}
This will add 10px of margin every time a .bar div follows a .foo div, or vice versa.
.foo + .bar,
.bar + .foo {
margin-top: 10px;
border-top: solid 1px black;
}
<div class="foo">Hello</div>
<div class="foo">World</div>
<div class="bar">Hotel</div>
<div class="bar">Romeo</div>
<div class="bar">Foxtrot</div>
<div class="foo">Ford</div>
<div class="foo">Prefect</div>

How to style nested divs

I want to change the colours of divs separately but don't want to use the following css.
The syntax I am using is as follows:
HTML:
<div id="wrapper"><div><div><div><div><div><div><div>
</div></div></div></div></div></div></div></div>
CSS:
div>div>div {background-color:yellow;}
div>div>div>div {background-color:green;}
div>div>div>div>div {background-color:indigo;}
div>div>div>div>div>div {background-color:violet;}
div>div>div>div>div>div>div {background-color:chocolate;}
div>div>div>div>div>div>div>div {background-color:brown;}
Your best/only easy solution is using Classes or Id's and attaching them to your CSS sheet (as per Daniel's answer).
HTML:
<div id="wrapper" class="ClassDiv1">
<div class="ClassDiv2">
<div class="ClassDiv3">
<div class="ClassDiv4">
<div class="ClassDiv5">
<div class="ClassDiv6">
<div class="ClassDiv7">
<div class="ClassDiv8">
CSS:
.ClassDiv1{background-color:yellow;}
.ClassDiv2{background-color:green;}
.ClassDiv3{background-color:indigo;}
etc.
If you want 1 color for 2 div tags you can just do this in your style:
.ClassDiv1 .ClassDiv2{background-color:brown;}
But seriously, rather go to W3Schools and learn a bit on CSS as it will help you a LOT!
Use a naming convention.
.innerDiv1{
background-color:yellow;
}
.innerDiv2{
background-color:green;
}
.innerDiv3{
background-color:indigo;
}
.innerDiv4{
background-color:violet;
}
.innerDiv5{
background-color:chocolate;
}
.innerDiv6{
background-color:brown;
}
or you can use a pre-processor like LESS and nested inside each other
.innerDiv{
background-color:yellow;
div{
background-color:green;
div{
background-color:indigo;
div{
background-color:violet;
div{
background-color:chocolate;
div{
background-color:brown;
}
}
}
}
}
}
I would go with classes:
.bg-yellow { background-color: yellow; }
...
.bg-brown { background-color: brown; }
HTML:
<div id="wrapper">
<div class="bg-yellow"><div><div><div><div><div><div class="bg-brown">
</div></div></div></div></div></div></div>
</div>
Using this solution makes it easier to identify the color of the element when inspecting the HTML.

Why CSS :not pseudo-class doesn't work as expected?

Consider the following HTML:
<div class="a">
<div class="b">Hello</div>
</div>
<div class="c">
<div class="b">World</div>
</div>
Adding the following CSS colors only "World" in red, as expected:
.c .b {
color: red;
}
But, adding the following CSS instead colors both "Hello" and "World" in red:
:not(.a) .b {
color: red;
}
Why?
You need to give it like this:-
Demo
div:not(.a) .b {
color: red;
}
Pseudo-class :not
Syntax is selector:not(){ properties }
Since the :not pseudo-class represents an element that is not represented by its argument,
you have to specify the element you want to exclude before the :not selector
Per your example, try this instead:
div:not(.a) .b {
color: red;
}

Resources