Reputation: 105
I’m trying to change the style of paragraph based on selected class. For example, I have a text that contain as a list of p elements. Based on some rules, I change the style of a single p element with a class 'alert'. In such a case, I want all paragraphs coming after it to have a unique style. The same applies for another class 'danger'. Alert comes first, and danger comes second. Both are optional. Both can be proceeded by other paragraphs that are not danger nor alert. Here is an example
<div class='text'>
<p>Some paragraph0</p>
<p class="alert">Alert</p>
<p>Some paragraph1</p>
<p>Some paragraph2</p>
<p class="danger">Danger</p>
<p>Some paragraph3</p>
<p>Some paragraph4</p>
</div>
The problem that I want the style changes to elements that come after p with either class alert or danger. So, I would have the options to say apply after or before p with class danger or alert.
.alert{
background: #FFFF00;
font-weight: bold;
}
.danger{
background: #F00;
font-weight: bold;
}
Upvotes: 0
Views: 176
Reputation: 5708
You can use javascript
to get it done. This will work in all situations
.
Works for elements of class="text"
that contain one element with class alert
or class danger
, or both.
If there are no elements
with class alert
or class danger
nothing will happen.
Here is the code: (run the snippet)
Note: I am giving the targeted elements
an example class
specialClass
, and there are two buttons at the bottom to simulate adding styles
before
and after
alert
or danger
.
function applyStyles(whenToStyle)
{
// get all elements with class 'text'
var elements = document.querySelectorAll('.text');
// go through all elements with class 'text'
for(var i=0; i< elements.length; i++)
{
// set all to false for new container of class 'text'
var alertSeen = false;
var dangerSeen = false;
var hasAlert = false;
var hasDanger = false;
// get the children in order as they appear on the page
var children = elements[i].children;
// check if elements with class 'alert' or 'danger' exist
if(elements[i].getElementsByClassName('alert').length > 0) hasAlert = true;
if(elements[i].getElementsByClassName('danger').length > 0) hasDanger = true;
// go through all children elements of the selected element
for(var j=0; j< children.length; j++)
{
// if the classList doesn't contain 'alert' or 'danger'
if(!children[j].classList.contains('alert') && !children[j].classList.contains('danger'))
{
if(whenToStyle == 'before')
{
if((!alertSeen && hasAlert) || (!dangerSeen && hasDanger))
{
children[j].classList.add('specialClass');
}
}
else if(whenToStyle == 'after')
{
if((alertSeen && hasAlert) || (dangerSeen && hasDanger))
{
children[j].classList.add('specialClass');
}
}
}
else
{
// mark if we are on an element with class 'alert' or 'danger'
if(children[j].classList.contains('alert')) alertSeen = true;
else if(children[j].classList.contains('danger')) dangerSeen = true;
}
}
}
}
.alert{
background: #FFFF00;
font-weight: bold;
}
.danger{
background: #F00;
font-weight: bold;
}
.specialClass
{
background-color:#09f;
color:#FFF;
font-size:1.3em;
}
<div class='text'>
<p>Some paragraph0</p>
<p class="alert">Alert</p>
<p>Some paragraph1</p>
<p>Some paragraph2</p>
<p class="danger">Danger</p>
<p>Some paragraph3</p>
<p>Some paragraph4</p>
</div>
<input type="button" value="click to apply before" onclick="applyStyles('before')" />
<input type="button" value="click to apply after" onclick="applyStyles('after')" />
Upvotes: 0
Reputation: 142
You can target them like this...
.alert p:not(:first-child) {color:orange;}
.danger p:not(:first-child) {color:purple;}
Upvotes: 1
Reputation: 2809
You can use the ~ selector, which can select elements preceded by danger or alert. I am following the assumption you are having in your case. The problem with this logic that it will not work properly with multiple warnings or dangers.
div.text p.alert ~ p:not(.danger), div.text p.alert {
background: #FFFF00;
}
div.text p.danger ~ p:not(.alert), div.text p.danger {
background: #F00;
}
div.text p.alert{
font-weight: bold;
}
div.text p.danger{
font-weight: bold;
}
Upvotes: 1
Reputation: 2113
This is a job for the general sibling selector!
.danger ~ p, .alert ~ p { // selects all paragraphs after a danger or alert tag
// css rules go here.
}
Upvotes: 0