css check previous element classes - css

So, in my code i have the following possibilities:
<div class="price-box">
<p class="was-old-price">$PRICE$</p>
<p class="special-price">$PRICE$</p>
</div>
or
<div class="price-box">
<p class="old-price">$PRICE$</p>
<p class="special-price">$PRICE$</p>
</div>
I want when .was-old-price get printed insted of .old-price, the .special-price has display:none properties. is this possible to achieve this using CSS?

You can do that with the the Adjacent Sibling Combinator (+) selector:
.was-old-price + .special-price {
display: none;
}
The E + F selector selects the F element immediately following the E element. In this case, the .special-price element immediately following the .was-old-price element. Here's an example:
.was-old-price + .special-price {
display: none;
}
<h3>Box 1</h3>
<div class="price-box">
<p class="was-old-price">was-old-price</p>
<p class="special-price">special-price</p>
</div>
<h3>Box 2</h3>
<div class="price-box">
<p class="old-price">old-price</p>
<p class="special-price">special-price</p>
</div>

Related

How do I hide only the first element of a parent class [duplicate]

This question already has answers here:
Can I combine :nth-child() or :nth-of-type() with an arbitrary selector?
(8 answers)
Closed 2 years ago.
I have the following markup:
.shwonlyclick {
display: none;
}
.asd>.delfirstdiv:first-child>.shwonlyclick:first-child {
display: block;
}
<div class="asd">
<div>title</div>
<div>sub title</div>
<div class="delfirstdiv">
<p class="shwonlyclick">Show this</p>
</div>
<div class="delfirstdiv">
<p class="shwonlyclick">Hide</p>
</div>
<div class="delfirstdiv">
<p class="shwonlyclick">Hide</p>
</div>
</div>
all tags are hidden, I only want the first one show. How?
Move your title and sub-title outside the parent div and fix your typo in your selector and it will work:
first-child is the first element inside it's parent (not the first element with a class name)
.shwonlyclick {
display: none;
}
.asd>.delfirstdiv:first-child>.shwonlyclick:first-child {
display:block;
}
<div>title</div>
<div>sub title</div>
<div class="asd">
<div class="delfirstdiv">
<p class="shwonlyclick">Show this</p>
</div>
<div class="delfirstdiv">
<p class="shwonlyclick">Hide</p>
</div>
<div class="delfirstdiv">
<p class="shwonlyclick">Hide</p>
</div>
</div>
if you are unable to change the html layout, then you can use the adjacent sibling combinator to hide any divs that follow another (which will mean the first is shown):
.delfirstdiv+.delfirstdiv .shwonlyclick {
display: none;
}
<div class="asd">
<div>title</div>
<div>sub title</div>
<div class="delfirstdiv">
<p class="shwonlyclick">Show this</p>
</div>
<div class="delfirstdiv">
<p class="shwonlyclick">Hide</p>
</div>
<div class="delfirstdiv">
<p class="shwonlyclick">Hide</p>
</div>
</div>

CSS select direct children, but not if inside another nested child

So, if this is the HTML of an element:
<div class="parent">
<div class="ignore-me">
<p class="child">ignore me</p>
<p class="child">ignore me</p>
<p class="child">ignore me</p>
<!-- I don't know how many <p> gonna be here -->
</div>
<p class="child">paint me green</p>
<p class="child">paint me blue</p>
</div>
How can I :
Select the children .child but not the ones inside the
div.ignore-me?
Select them separately, based on their index order.
I tried to use a mix of > and :nth-child(n) like this:
.parent > .child:nth-child(1)
But, it doesn't work!
Can this be done only CSS?
.parent > .child:nth-child(1) {
background: green;
}
.parent > .child:nth-child(2) {
background: blue;
}
<div class="parent">
<div class="ignore-me">
<p class="child">ignore me</p>
<p class="child">ignore me</p>
<p class="child">ignore me</p>
<!-- I don't know how many <p> gonna be here -->
</div>
<p class="child">paint me green</p>
<p class="child">paint me blue</p>
</div>
Use div.parent > p.p
> is the child combinator. It matches only those elements matched by the second selector that are the direct children of elements matched by the first.
div.parent > p.p {
color:green;
}
<div class="parent">
<div class="ignore-me">
<p class="p">don't select me</p>
<p class="p">don't select me</p>
<p class="p">don't select me</p>
<!-- I don't know how many <p> gonna be here -->
</div>
<p class="p">select me</p>
<p class="p">select me too</p>
</div>
The accepted answer can be further simplified to div.parent > p, because > already only selects direct children.
div.parent > p {
color:green;
}
<div class="parent">
<div class="ignore-me">
<p>don't select me</p>
<p>don't select me</p>
<p>don't select me</p>
<!-- I don't know how many <p> gonna be here -->
</div>
<p>select me</p>
<p>select me too</p>
</div>
Regarding
Select them separately, based on their index order.
you can use :nth-child, but be aware that :nth-child also counts <div class="ignore-me"> as a child of <div class="parent">. So your first <p class="child"> is the second child. You can then use even and odd to alternate between the children.
div.parent > p {
color:green;
}
div.parent > p:nth-child(odd) {
color:blue;
}
<div class="parent">
<div class="ignore-me">
<p class="child">ignore me</p>
<p class="child">ignore me</p>
<!-- I don't know how many <p> gonna be here -->
</div>
<p class="child">paint me green</p>
<p class="child">paint me blue</p>
<p class="child">paint me green</p>
<p class="child">paint me blue</p>
</div>
Selecting direct nth p tag inside "parent" class
div.parent>p.child:nth-child(2) {
background: green;
}
div.parent>p.child:nth-child(3) {
background: blue;
}
div.parent>p.child:nth-child(4) {
background: green;
}
we can slect odd and event children
div.parent>p.child:nth-child(odd) {
background: green;
}
div.parent>p.child:nth-child(even) {
background: red;
}

css/sass :not(:first-of-type) not working, is hiding all elements of type

I have a sass block that i have tried several different ways:
I've tried this:
.progress-body {
display: none;
&:first-of-type {
display: block;
}
}
and this:
.progress-body {
&:not(:first-of-type) {
display: none;
}
}
and this:
.progress-body:not(:first-of-type) {
display: none;
}
when applied to HTML that looks like this:
<div class="panel">
<div class="panel-heading">
</div>
<div class="panel-body progress-body">
<div class="row">
<div class="col-md-12">
<p class="lead">Step 1: Choose your template...</p>
</div>
</div>
</div>
<div class="panel-body progress-body">
<div class="row">
<div class="col-md-12">
<p class="lead">Step 2: Compose your email...</p>
</div>
</div>
</div>
</div>
the result is that it hides all the elements with the progress-body class. This is normally pretty straight forward CSS so no idea what is wrong here...
In this case progress-body is not the first-of-type, this would technically be .panel-heading since the first-of-type refers to the type element selector (div) and not the class.
The :first-of-type CSS pseudo-class represents the first element of
its type among a group of sibling elements.
Ref: :first-of-type - CSS | MDN
Consider wrapping your .progress-body elements in a containing element, you will achieve the expected behaviour, since .progress-body would be the first of its type with the class name .progress-body.
Code Snippet Demonstration:
.progress-body:not(:first-of-type) {
display: none;
}
<div class="panel">
<div class="panel-heading">
</div>
<div class="panel-outer-body">
<div class="panel-body progress-body">
<div class="row">
<div class="col-md-12">
<p class="lead">Step 1: Choose your template...</p>
</div>
</div>
</div>
<div class="panel-body progress-body">
<div class="row">
<div class="col-md-12">
<p class="lead">Step 2: Compose your email...</p>
</div>
</div>
</div>
</div>
</div>
If you can't wrap as UncaughtTypeError wrote in his answer, youcan use (general) sibling selectors.
.progress-body + .progress-body {display: none;}
or
.progress-body ~ .progress-body {display: none;}
I expect the first is block by default, if you didn't change it elsewhere.

CSS Grab All Class Name Except For Last

I want to grab all the class name ('my-class') and change it's color to red EXCEPT for the last one
Apparently I've been googling and there's no such thing as :last-of-class or whatever. I'm having trouble trying to find a work around without using JS.
div1 and div2 are both dynamic! If div2 doesn't exist, then div1 should have the first p element red and the second not.
Please note I left a 'p' tag at the top because I don't want that being part of my selector. I just need the 'my-class' specifically.
or is there a selector I can write to grab all "p"s inside of my-container which include nested P's
<p>Some text</p>
<div class="my-container">
<div class="div1">
<p class="my-class"></p>
<p class="my-class"></p>
</div>
<div class="div2">
<p class="my-class"></p>
<p class="my-class"></p>
<p class="my-class"></p>
<p class="my-class"></p> <!-- This tag should not be red-->
</div>
</div>
I can also use sass so feel free to include that in if need be.
I don't know of any SINGLE rule that would do this, but a simple workaround would be to use 2 separate rules in conjunction:
.my-class {
color: red;
}
.div-2 .my-class:last-child {
color: // whatever you want the default to be
}
note that the order is important, setting the last child's color should be done after setting everything first
You can use the workaround below.
use div:last-child . that will select the last div in the container and if there is only one, it will select it and so...the last p from the last div will be of other color ( in this example )
.my-container div p.my-class {
color:red;
}
.my-container div:last-child p.my-class:last-child {
color:blue;
}
<p>Some text</p>
<div class="my-container">
<div class="div1">
<p class="my-class">a</p>
<p class="my-class">a</p>
</div>
<div class="div2">
<p class="my-class">a</p>
<p class="my-class">a</p>
<p class="my-class">a</p>
<p class="my-class">b</p> <!-- This tag should not be red-->
</div>
</div>
This will get the behavior you're looking for without any forced reflow:
.my-class:not(:last-child) {
color: red;
}
<p>Some text</p>
<div class="my-container">
<div class="div1">
<p class="my-class">a</p>
<p class="my-class">b</p>
</div>
<div class="div2">
<p class="my-class">c</p>
<p class="my-class">d</p>
<p class="my-class">e</p>
<p class="my-class">f</p> <!-- This tag should not be red-->
</div>
</div>

CSS - first-child selector not working

I am using bulma as css framework, and have a section on my page where I am looping over items, and creating multiline columns.
<section class="section employees">
<div class="container">
<div v-for="(value, key) of employeesGroupedByDepartments">
<div class="columns is-multiline department">
<div class="title-with-line">
<h4><span>{{ key }}</span></h4>
</div>
<div class="employee column is-3" v-for="employee of value">
<div class="card">
<figure class="image is-96x96">
<img :src="employee.image.data.path" alt="">
</figure>
<h4 class="title is-5">
{{employee.title}}
</h4>
<h6 class="subtitle is-6">
<small>
{{getExtras(employee, 'position')}}
</small>
</h6>
</div>
</div>
</div>
</div>
</div>
</section>
I would like to remove left padding for each first child column, I have tried with setting even to both classes padding left 0 as important but nothing worked:
.employees {
.column:first-child, employee:first-child {
padding-left: 0!important;
}
}
What am I doing wrong?
A .column will never be a first-child, because there is always a div.title-with-line before it.
From MDN:
The :first-child CSS pseudo-class represents the first element among a group of sibling elements.
You would need the :nth-child or :nth-of-type selector.
.column is not the first child as you have a div with class title-with-line proceeding it. What you're looking for is:
.employees {
.column:nth-child(2), .employee:nth-child(2) {
padding-left: 0!important;
}
}

Resources