Selecting all but the last element with specific class - html

I need to apply a style to text in all children divs except the one that has a span with class .fa
.parentDiv > .column :not(.fa) {
font-weight: bold
}
<div class="parentDiv">
<div class="column">aaa</div>
<div class="column">bbb</div>
<div class="column">
<span class="fa">ccc</span>
</div>
</div>
I do need to keep CSS in one line as it's a part of a larger style sheet. How do I do that?

You can use :not with :last-of-type
Snippet
.parentDiv > .column:not(:last-of-type) {
font-weight: bold;
color:red;
}
<div class="parentDiv">
<div class="column">aaa</div>
<div class="column">bbb</div>
<div class="column">
<span class="fa">ccc</span>
</div>
</div>
EDIT based on #Oriol's comment
:not(:last-of-type) does not mean "doesn't contain a .fa
which makes sense, if your code could be dynamic.
here is another approach:
Snippet
.parentDiv > .column span:not(.fa) {
font-weight: bold;
color: red;
}
<div class="parentDiv">
<div class="column">
<span class="gsdfasd">text</span>
</div>
<div class="column">
<span class="faadsasfa">some text</span>
</div>
<div class="column">
<span class="fa">this will NOT BE red</span>
</div>
</div>

The only way to do this is to use
.parentDiv > .column { font-weight: bold }
.parentDiv > .column > .fa { font-weight: normal }

The way the not() selector works is that you have to target a specific element/class/ID. You would have to wrap the text from each column in a span and then add the :not(.fa) CSS to the span:
.parentDiv > .column span:not(.fa) {
font-weight: bold
}
<div class="parentDiv">
<div class="column">
<span>aaa</span>
</div>
<div class="column">
<span>bbb</span>
</div>
<div class="column">
<span class="fa">ccc</span>
</div>
</div>

Related

CSS selector to target img that is NOT in another element [duplicate]

This question already has answers here:
CSS negation pseudo-class :not() for parent/ancestor elements
(2 answers)
Closed 4 years ago.
Check this code below:
.aaa :not(.bbb) .ccc {
font-size: 20px;
color: #FF0000;
}
<div class="aaa">
<div>
<div>
<div class="bbb">
<div>
<div>
<div class="ccc">AQUI</div>
</div>
</div>
</div>
</div>
</div>
</div>
I want to match all .ccc element that are children of .aaa but are not children of .bbb. It means that the code above should NOT make the AQUI word be RED, but it gets RED anyway. What am I doing wrong?
There are actually elements which are not .bbb - the two divs before and after .bbb in this case. For this to work, you'll need to be more specific. You can add another class (zzz in the example), and if this class is not combined with .bbb the rule will be applied.
.aaa .zzz:not(.bbb) .ccc {
font-size: 20px;
color: #FF0000;
}
<div class="aaa">
<div>
<div>
<div class="zzz bbb">
<div>
<div>
<div class="ccc">AQUI</div>
</div>
</div>
</div>
</div>
</div>
</div>
The not(.bbb) will match any div without the class .bbb and you have a lot of them between .aaa and .ccc that why the text is red. To do what you want you need to consider two selectors
.aaa .ccc {
font-size: 20px;
color: #FF0000;
}
/*we reset the style if children of .bbb*/
.bbb .ccc {
color: initial;
font-size:initial;
}
<div class="aaa">
<div>
<div>
<div class="bbb">
<div>
<div>
<div class="ccc">AQUI</div>
</div>
</div>
</div>
</div>
</div>
</div>
You have overlooked that the .ccc is a child of components that match :not(.bbb):
<div class="aaa">
<div class="ccc"></div>
<div class="bbb">
<div> // <-- :not(.bbb)
<div class="ccc"></div>
</div>
</div>
</div>
You need to write two rules:
.aaa .ccc {
color: blue;
}
.aaa .bbb .ccc {
color: red;
}

CSS: Add pipe on all div except last

I need to add pipe between links except after the last . My html is rendered in the following way , html is rendered with same class.
<!DOCTYPE html>
<html>
<head>
<style>
p:last-of-type {
background: #ff0000;
}
</style>
</head>
<body>
<h1>This is a heading</h1>
<div class="sample" style="display:inline-block">
<div >
<p class="para">link1</p>
</div>
</div>
<div class="sample" style="display:inline-block">
<div >
<p class="para">link1</p>
</div>
</div>
<div class="sample" style="display:inline-block">
<div >
<p class="para">link1</p>
</div>
</div>
</body>
</html>
I need to add Pipe but after last link no pipe should be displayed . How can i do it for this case .
Fiddle Link
P.S. : This can be done easily when we have different links with different class . In my case links are dynamic and after last link no pipe should be displayed
Use this selector .sample:not(:last-of-type), which will target all but the last item.
Do note, when combining a class name with last-of-type, it will target any element type not being the last (if there is more than 1) having the given class.
Updated fiddle (added the pipe to the div so it won't pick up the color from the p)
.sample:not(:last-of-type) > div::after {
content: ' | ';
}
Another option is last-child, .sample:not(:last-child), which also will target all but the last.
Do note, when using last-child, it means the last no matter class or element type, so if you have another element coming after the last sample, that will count as the last, and here is a fiddle sample showing how this rule will fail in cases like that.
Updated fiddle (added the pipe to the div so it won't pick up the color from the p)
.sample:not(:last-child) > div::after {
content: ' | ';
}
A third option is to use the immediate sibling selecor +, which target all sibling elements with the given class but the first.
p:last-of-type {
background: #ff0000;
display: inline-block;
}
.sample + .sample > div::before {
content: ' | ';
}
<h1>This is a heading</h1>
<div class="sample" style="display:inline-block">
<div >
<p class="para">link1</p>
</div>
</div>
<div class="sample" style="display:inline-block">
<div >
<p class="para">link1</p>
</div>
</div>
<div class="sample" style="display:inline-block">
<div >
<p class="para">link1</p>
</div>
</div>
Here's another way:
'Add a pipe before each link - only if it comes after another one'
.sample + .sample .para:before {
content: "|";
margin-right: 10px;
color: red;
}
.sample + .sample .para:before {
content: "|";
margin-right: 10px;
color: red;
}
<h1>This is a heading</h1>
<div class="sample" style="display:inline-block">
<div >
<p class="para">link1</p>
</div>
</div>
<div class="sample" style="display:inline-block">
<div >
<p class="para">link1</p>
</div>
</div>
<div class="sample" style="display:inline-block">
<div >
<p class="para">link1</p>
</div>
</div>
I think you want like this.
.sample:last-child div {
border: none;
}
.sample div {
border-right: 1px solid #000;
margin-right: 10px;
padding-right: 10px;
}
<h1>This is a heading</h1>
<div>
<div class="sample" style="display:inline-block">
<div>
<p class="para">link1</p>
</div>
</div>
<div class="sample" style="display:inline-block">
<div>
<p class="para">link1</p>
</div>
</div>
<div class="sample" style="display:inline-block">
<div>
<p class="para">link1</p>
</div>
</div>
</div>
One way to do it is to add this CSS rule:
.sample:not(:last-of-type) {
border-right: 1px solid black;
}
https://jsfiddle.net/9c8szuc5/2/

Color change on hover over multiple elements

I want to apply one for all hover color change effect on the icon, text and button(top to bottom). At the moment hover is working separately either text and icon or button is changing color.
here is the code and also a fiddle
<div class="col-1-left">
<div class="content">
<div class="icon">
<img src="#" />
</div>
<div class="text">
<h4>
Title text
</h4>
</div>
</div>
<div class="button">
Read More
</div>
</div>
.col-1-left {
width: 100%;
background: #555;
padding: 10px;
margin: 0;
color: red;
}
.col-1-left:hover {
color: white;
}
.button a {
color: #000;
}
.button a:hover {
color: white;
}
EDIT:
Although some of the answers worked on jsfiddle, none of them worked so far on live site.. I am pasting updated HTML code structure from it as the one above was only a sample. Maybe that will help sorting this issue out. Thanks!
<div class="et_pb_column et_pb_column_1_3 col-1-left et_pb_column_93 cboxElement">
<div class="et_pb_blurb et_pb_module et_pb_bg_layout_light et_pb_text_align_center mp_m_blurb_pulse fins-color-aqua et_pb_blurb_50 et_pb_blurb_position_top">
<div class="et_pb_blurb_content">
<div class="et_pb_main_blurb_image">
<span class="et-pb-icon et-waypoint et_pb_animation_off et-animated" style="color: #28375c;">?</span>
</div>
<div class="et_pb_blurb_container">
<h4>Title</h4>
<h5>Subhead</h5>
</div>
</div>
</div>
<div class="et_pb_button_module_wrapper et_pb_module et_pb_button_alignment_center">
<a class="et_pb_button et_pb_button_26 et_pb_module et_pb_bg_layout_dark" href="#">Find Out More</a>
</div>
</div>
Please Try this,
.col-1-left:hover * {
color: white;
}
I did a code snippet for you. Please try it and confirm it is what you need.
The thing is that you need to add the hover effect to the parent, i.e. .col-1-left in order to be able to change the color to its children elements.
.col-1-left {
width: 100%;
background: #555;
padding: 10px;
margin: 0;
color: red;
}
.col-1-left:hover, .col-1-left:hover .button a {
color: white;
}
.button a {
color:#000;
}
<div class="col-1-left">
<div class="content">
<div class="icon">
<img src="#" />
</div>
<div class="text">
<h4>Title text</h4>
</div>
</div>
<div class="button">
Read More
</div>
</div>

Force text over 2 lines with CSS

I'd like to have all surnames on the second line AND maintain the exact same width for test div. What is the best way of achieving this with CSS?
HTML:
<div class="test">
<h1>Mike S</h1>
</div>
<div class="test">
<h1>Mike Smith</h1>
</div>
<div class="test">
<h1>Mike Smiths</h1>
</div>
CSS:
.test {width:25%;float:left;background:red;margin-right:20px}
h1 {text-align:center}
http://jsfiddle.net/zcg9k5xh/
Update your code with this:
.test {width:25%;float:left;background:red;margin-right:20px}
h1 {text-align:center}
h1 span{display: block;}
<div class="test">
<h1>Mike <span>S</span></h1>
</div>
<div class="test">
<h1>Mike <span>Smith</span></h1>
</div>
<div class="test">
<h1>Mike <span>Smiths</span></h1>
</div>
You can also do this by using css, update above css
h1 span{display: list-item;list-style:none;}
jsfiddle with this
http://jsfiddle.net/zcg9k5xh/2/
Given that it seems you are willing to change your HTML, I would recommend you simply add <br> after the first name, instead of wrapping the last name in any other tags. This would be deemed best practice.
The HTML <br> Element (or HTML Line Break Element) produces a line
break in text
This will give more semantic HTML- without the need to adjust native element styling, or clutter your DOM with uneccessary nodes.
.test {
width: 25%;
float: left;
background: red;
margin-right: 20px
}
h1 {
text-align: center
}
<div class="test">
<h1>Mike<br>S</h1>
</div>
<div class="test">
<h1>Mike<br>Smith</h1>
</div>
<div class="test">
<h1>Mike<br>Smiths</h1>
</div>
Use the word-spacing attribute to the child tag:
.test {
width: 25%;
float: left;
background: red;
margin-right: 20px
}
h1 {
background-color: blue;
word-spacing: 100px;
}
<div class="test">
<h1>Mike S</h1>
</div>
<div class="test">
<h1>Mike Smith</h1>
</div>
<div class="test">
<h1>Mike Smiths</h1>
</div>
I don't see what you are asking, it seems like the jsfiddle is what you are asking here.
But you can always set width to 100% so it cover for the text, if you want all that text in the same div then put it all under one Div tag.
Is this what you want?
.test {width:25%;float:left;background:red;margin-right:20px}
h1 {text-align:center}
<div class="test">
<h1>Mike</h1>
<h1>S</h1>
</div>
<div class="test">
<h1>Mike</h1>
<h1>Smith</h1>
</div>
<div class="test">
<h1>Mike</h1>
<h1>Smiths</h1>
</div>

"display: table-cell" has no constistent alignment

Once between the div tags, an HTML tag (eg headings, breaks), the contents are no longer align the same. Example: Html.DisplayFor (...) should end always justified. How can this be fixed?
<div class="table">
<div class="row">
<div class="cell">
<h3>Heading 1</h3>
<hr />
<div class="row">
<div class="cell">Label 1</div>
<div class="cell">Html.DisplayFor(...)</div>
</div>
<div class="row">
<div class="cell">Label 2 with much more Text</div>
<div class="cell">Html.DisplayFor(...)</div>
</div>
<br />
<h3>Heading 2</h3>
<hr />
<div class="row">
<div class="cell">Label 3 with Text</div>
<div class="cell">Html.TextBoxFor(...)</div>
</div>
</div>
<div class="cell">
...
</div>
</div>
</div>
CSS:
div .table {
display: table;
width: 100%;
}
div .cell {
display: table-cell;
padding: 0.3em;
}
div .row {
display: table-row;
}
It should actually look more like this (red line):
Its because you break the flow of the layout by not adhering to only using a table->row/cell structure but by injecting div and hr elements in the middle of it.
You could simply add a width to the first column:
.row .cell .row .cell:first-child{
width:200px;
}
Demo Fiddle