This question already has answers here:
CSS selector for first element with class
(23 answers)
Closed 6 years ago.
I'm trying to style a certain <div> in my markup with CSS/SASS, and I'm clueless as to why it's not applying the rules. This is my markup:
<div class="row addon-header">
<div class="col-sm-3">
// something here
</div>
<div class="col-sm-9">
<h2>Title</h2>
<h6><em>Slogan</em></h6>
<div class="col-xs-1">
// I want to access this
</div>
<div class="col-xs-1"></div>
<div class="col-xs-1"></div>
<div class="col-xs-1"></div>
</div>
</div>
And this is the SASS I'm trying to use for it:
div.addon-header {
color: white;
> div.col-sm-9 > div.col-xs-1:first-child {
background-color: black;
padding-left: 0px !important;
}
}
If I remove the :first-child selector in my SASS, it's working, but obvious for every <div class="col-xs-1"> not just the first one, which is not what I want.
I also tried playing around and doing something like
div.addon-header {
color: white;
> div.col-sm-9 > div.col-xs-1 {
&:first-child {
background-color: black;
padding-left: 0px !important;
}
}
}
or
div.addon-header {
color: white;
> div.col-sm-9 {
> div.col-xs-1:first-child {
background-color: black;
padding-left: 0px !important;
}
}
}
or using :nth-child(1) instead. Nothing works. I'm clueless. Somewhere else in my SASS, I have the following:
.tab-content {
>.tab-pane:first-child > form > div.row > div {
// rules here
> div.picture-container {
// rules here
}
}
>.tab-pane {
// rules here
}
>.tab-pane:nth-child(4) > form {
// rules here
}
}
Which is working just fine. So I really don't get what I'm doing wrong in the first example. Anyone able to help?
You need the :nth-of-type() (or, in your case, the :first-of-type selector).
In the example your provided the :first-child of .col-sm-9 element is the h2.
div.addon-header {
color: white;
> div.col-sm-9 > div.col-xs-1:first-of-type {
background-color: black;
padding-left: 0px !important;
}
}
Note, though, that the :nth-of-type() selectors, like the :nth-child() selectors, apply to tags only, not class names; if you were to insert another div before the first .col-xs-1 then this would no longer work.
col-xs-1 need to wrap row because this block is not first element. First element is h2
Related
While I know you can't write variables like
root: {
--aic: align-items:center;;
}
Is there anyway to get round this, by combining the various parts seperately? The obvious obstical here is the requirement of the colon inside the variable.
i.e.
root: {
--ai: align-items:;
--center: center;
--aic:
var(--ai)
var(--center);
}
.myclass {var(--aic);}
I would suggest you to switch to SCSS and use a #mixin. Read more about it here.
Here's a live demo.
HTML:
<div id="test">TEST</div>
SCSS:
:root {
--text_color: red;
--background_color: gold;
}
#mixin my_mixin {
color: var(--text_color);
background-color: var(--background_color);
}
#test {
#include my_mixin;
}
Based on my comment on your question, you can use classes to achieve something similar. But you can't use custom properties as CSS properties, only values -- it's the same as saying for example margin: margin: var(--customMargin);;
/* Layout unrelated to answer */
div { border: 1px solid black; color: white }
.varText { background-color: red }
.varPad { background-color: blue }
.varText.varPad { background-color: green }
/* Answer */
:root { --size: 1rem }
.varText { font-size: var(--size) }
.varPad { padding: var(--size) }
<div class="varText">
Size Text only to root variable
</div>
<div class="varText" style="--size: 2rem">
Size Text only to inline variable
</div>
<div class="varPad">
Size Padding only to root variable
</div>
<div class="varPad" style="--size: 2rem">
Size Padding only to inline variable
</div>
<div class="varText varPad">
Size Text and Padding to root variable
</div>
<div class="varText varPad" style="--size: 2rem">
Size Text and Padding to inline variable
</div>
This question already has answers here:
Is there a CSS selector by class prefix?
(4 answers)
combined multiple classes into one css rule
(3 answers)
Closed 4 years ago.
For instance, I have the following code in a .less file, and would like to simplify it. Each nav is an individual navigation point. When the user hovers over that nav point, I only want that particular nav point's background color to change. Not every single one of them.
.nav-1:hover {
background:#fc9426;
}
.nav-2:hover {
background:#fc9426;
}
.nav-3:hover {
background:#fc9426;
}
.nav-4:hover {
background:#fc9426;
}
.nav-5:hover {
background:#fc9426;
}
.nav-6:hover {
background:#fc9426;
}
.nav-7:hover {
background:#fc9426;
}
.nav-8:hover {
background:#fc9426;
}
.nav-9:hover {
background:#fc9426;
}
Use a comma.
.nav-1:hover,
.nav-2:hover,
.nav-3:hover {
color: #fc9426;
}
Although I don't have any markup to go off of, it looks like you could create a helper/modifier class instead of defining the same thing over and over again.
It might look something like this:
[class^="nav-"] {
margin: 1rem 0;
padding: 0 1rem;
min-height: 3rem;
color: #333;
font: 1rem/3rem Arial, sans-serif;
border-bottom: 1px solid black;
}
/**
* Utility/Modifier style properties that
* any nav could add to their base of styles.
*/
.nav-branded {
color: white;
background-color: #fc643c;
}
.nav-branded:hover {
background-color: hotpink;
}
/**
* These classes have styles specific to
* each class (acts like an ID but
* without the specificity).
*/
.nav-1 {
/* Waiting for some styles. */
}
.nav-2 {
border-bottom-width: 4px;
}
.nav-3 {
border-bottom-style: dashed;
}
<nav class="nav-1 nav-branded">Nav One</nav>
<nav class="nav-2">Nav Two</nav>
<nav class="nav-3 nav-branded">Nav Three</nav>
CSS classes are meant to be re-used so you don't have to define a bunch of different ones to get the same styling.
The point of classes is for a given property to apply to a variety of elements. So you should give each <nav> the same class.
<nav class='color-change'>
.
.
.
</nav>
Then in your CSS / LESS:
.color-change:hover {
background:#fc9426;
}
I think you imagine that you have a code like this
<div class="nav-1"> </div>
<div class="nav-2"> </div>
<div class="nav-3"> </div>
<div class="nav-4"> </div>
If so, you could simplify the code with a better advanced selector
[class*='nav-']{
background:#fc9426;
}
In this way, you will select the elements that in the 'class' attribute have in any part of the code the word 'nav-', which is the piece of the name of the class in common
In the case that in the HTML they have a father
<div class="nav">
<div class="nav-1"> </div>
<div class="nav-2"> </div>
<div class="nav-3"> </div>
<div class="nav-4"> </div>
</nav>
you can use this CSSs
.nav > div{}
.nav [class*='nav-']{}
.nav > div:nth-of-type(1){} /* the number of the son */
.nav > div:nth-of-type(2n){} /* all the pairs */
.nav > div:nth-of-type(2n+1){} /* all the odd */
If you can't change your markup to avoid the redundancy of selectors, you can use an attribute selector to catch all of those classes with a single specifier:
*[class*="nav-"]:hover, *[class*=" nav-"]:hover {
background:#fc9426;
}
The question was originally tagged with less, so if using less, you can also use recursion to generate those classes individually. This task is featured in the manual:
.generate-navs(9);
.generate-navs(#n, #i: 1) when (#i =< #n) {
.nav-#{i}:hover {
background:#fc9426;
}
.generate-navs(#n, (#i + 1));
}
I have three class : product1, product2, product3. I can add css to all these class as follows:
.product1, .product2, .product3{
// add css here
}
But I am looking for more cleaner code to track 1 to 3 followed by 'product' and add css to these. My expectation can be Pseudocode Examples:
.product1to3{
// fun with css.
}
Is there any approach in css?
There is no such kind of css pseudo on what you wanted to achieve.
You can try to use SASS to achieve what you wanted.
and then use the #for Directive
SASS
#for $i from 1 through 3 {
.product#{$i} { width: 20px; }
}
CSS
.product1 {
width: 20px;
}
.product2 {
width: 20px;
}
.product3 {
width: 20px;
}
Also you can try to use LESS
Hope this helps
pure css implementation JSfiddle
So basically you need an "Attribute Begins With Selector" i.e select all classes which start with "product" and then you can use nth child attribute to select range
div[class^="product"]:nth-child(n+4):nth-child(-n+5) {
background: red;
}
Really good article on complex css and nth:child
/* This selects all the elements which have the class name starting with
"product"
*/
[class ^= "product"] {
//CSS
}
If you have an unknown / high number of ".product(x)", and for whatever reason don't want to use an extra class to target them, you can get away with an attribute selector that matches all elements that have a class containing "product".
[class*="product"]
div{
border:2px solid tan;
height:40px;
}
[class*="product"]{
background:steelblue;
}
<div class="product1"> product 1 </div>
<div class="product2"> product 2 </div>
<div class="not"> not a product</div>
<div class="product3"> product 3 </div>
<div class="product4"> product 4 </div>
It occupies just 1 line of compiled CSS, so it's minimal footprint, but be careful how you apply it.
Not an answer for the OP but for others that may find their way here remember that you can use multiple classes for each element.
html
<div class="product product1"></div>
<div class="product product2"></div>
<div class="product product3"></div>
css
/* shared styling */
.product {
display: flex;
background-color: gray;
border: 1px solid red;
}
/* individual styling */
.product1 {
color: black;
}
.product2 {
color: white;
}
.product3 {
color: blue;
}
I understand that I can change another element's style when hovering on a different element like this:
.element-one:hover .element-two {
opacity: 0.8;
}
But how can I change the style of all the elements in the page except element-two when I hover on element-one?
You can use .element-one:hover :not(.element-two).
Here is an example:
.element-one:hover :not(.element-two) {
opacity: 0.8;
}
.element-one {
background: black;
margin: 10px;
}
.element-one div {
background: green;
border: 1px solid blue;
margin: 10px;
padding: 10px;
}
<div class="element-one">
<div class="element-two">
element-two
</div>
<div class="element-three">
element-three
</div>
<div class="element-four">
element-four
</div>
</div>
However - note that it will work only for elements inside element-one and not for all the elements in the page.
You can do this with body for example, but the problem there is that .element-two is probably also inside some other element that exists inside body, and in such case the .element-two will get the opacity from it's containing element.
Lets say I have the following html:
<header class="header">
<div class="title">
<h1>Home</h1>
</div>
<div class="logo">
<img src="#" alt="Logo">
</div>
<div class="account">
<div class="options">
</div>
<div class="search">
</div>
</div>
</header>
And I have the following SCSS:
header {
height: 4.1rem;
div {
width: 33%;
float: left;
height: 4.1rem;
line-height: 4.1rem;
color: #fff;
&.title {
h1 {
font-weight: normal;
font-size: 3rem;
padding: 0;
margin: 0;
}
}
&.logo {
text-align: center;
}
&.account {
}
}
}
Now the problem that I have is that divs options and search are 33% percent of account which is logic as I have div {width: 33%}. I know I can select direct child elements with:
header {
> div {
}
}
But this doesn't help even if I put the > infront of all other classes. I also know I can say that the width should be 0 or what ever again in .account but I would like to prevent this.
Try this:
...
& > div {width: 33%;}
div {
float: left;
height: 4.1rem;
line-height: 4.1rem;
color: #fff;
...
Take out div width and apply it only on direct children. Leave rest as is.
Here is quick fiddle (remove .option and .search styles later, its only for visualisation).
Please edit your question and better explain what exactly you want to achieve.
Use the & with > inside the parent element like this:
.services {
& > div {
margin-bottom: 25px;
}
}
I am not certain I understand you. But I think you want a combination of direct children and child pseudo selectors, in pure CSS:
header > div:first-child {
}
Or, for the second div:
header > div:nth-child(2) {
}
You could also use the not selector:
header > div:not(.account) {
}
to exclude any unwanted div's.