CSS3: add style if there are no children - css

I'm trying to write a scss selector that will add style to the header-cart class but only when it doesn't have content inside.
I can use JS, but I think it is possible to write it in scss.
Before AJAX loaded:
<div class="dropdown-menu dropdown-menu-right header-cart-dropdown">
<div class="header-cart">
</div>
</div>
After AJAX loaded:
<div class="dropdown-menu dropdown-menu-right header-cart-dropdown">
<div class="header-cart">
<div class="offcanvas-content-container">
<div class="offcanvas-cart">
</div>
</div>
</div>
</div>
So far I have managed to write something like this, but it does not work correctly:
.dropdown-menu > {
div {
&:not(.has-element-loader:has(.offcanvas-content-container)) {
border: 5px solid green;
}
}
}

You can use the :empty pseudo-class:
.dropdown-menu > div.header-cart:not(:empty) {
border: 5px solid green;
}
.dropdown-menu > div.header-cart:empty {
border: 5px solid pink;
}
<div class="dropdown-menu dropdown-menu-right header-cart-dropdown">
<div class="header-cart"></div>
</div>
<div class="dropdown-menu dropdown-menu-right header-cart-dropdown">
<div class="header-cart">
<div class="offcanvas-content-container">
<div class="offcanvas-cart"></div>
</div>
</div>
</div>
This shows that an empty div would receive the pink border, while a div with content would receive a green border.

Maybe you could use :empty pseudo-class
https://developer.mozilla.org/en-US/docs/Web/CSS/:empty#:~:text=The%20%3Aempty%20CSS%20pseudo%2Dclass,an%20element%20is%20considered%20empty.

Related

Reduce the bottom border width

I have two tabs and they have bottom-borders. This is the jsfiddle example.
<div class="component-content">
<div class="tabs-inner">
<ul class="tabs-heading">
<li tabindex="0" class="active">
<div>
<div class="row">
<div class="component content col-12">
<div class="component-content">
<div class="field-heading">TAB 1: STANDARD SMALL</div>
</div>
</div>
</div>
</div>
</li>
<li tabindex="-1">
<div>
<div class="row">
<div class="component content col-12">
<div class="component-content">
<div class="field-heading">TAB 2: STANDARD SMALL</div>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
.tabs-heading {
display: table;
table-layout: fixed;
width:100%;
}
.tabs-heading li {
display: table-cell;
border-bottom: 2px solid red;
}
I want to add padding in the border bottom so that it should look like this
I tried to add padding-bottom but it didn't work.
Any suggestion or help would be appreciated
I am not quite sure if I got your question right ... but maybe you are looking for something like this ...?
If you don't use table and table-cell ... but flexbox instead ... all tabs will get automatically the same height and you are able to work with padding-bottom. If you like you can add margins between tabs as well.
#wrapper {
display: flex;
align-items: stretch;
background-color: Gray;
}
#wrapper div {
padding-bottom: 10px;
border-bottom: 2px solid orange;
}
#one {
background-color: green
}
#two {
background-color: blue
}
#three {
background-color: red
<div id="wrapper">
<div id="one">one one one one one one one one one one one one one one one one one one one one one</div>
<div id="two">two two two two two two</div>
<div id="three">three</div>
</div>

css find closest item

I have a nested structure that contains the same elements. To only target the elements within the current set I do something like this:
.set1 > .content > .trigger {
background: red;
}
In real life this selector has much more elements. While it works, if I change the name or depth on one of the elements it will no longer work.
Is there a way to just find the .trigger (in this case) of the current set?
<div class="set set1">
<div class="content">
<div class="trigger"></div>
<div class="set set2">
<div class="content">
<div class="trigger"></div>
</div>
<div>
</div>
<div>
You can apply a style on all triggers inside the current set and then remove the style for the other triggers that comes after the first trigger.
div {
padding: 5px;
border: 1px solid;
}
.set1 .trigger {
background: red;
}
.set1 .trigger ~ .set .trigger {
background: none;
}
<div class="set set1">
<div class="content">
<div class="trigger"></div>
<div class="set set2">
<div class="content">
<div class="trigger"></div>
</div>
</div>
</div>
</div>

Using Sass to change class

I'm trying to grey out the tags (success and recommended on the last 2 boxes) and have them colored only when they are hovered over or active (the first box).
I'm using the gray colour as a disabled state although its just styled gray using css.
I'm trying to do this in in pure CSS using SASS and not using css fitler as I need to target IE browsers.
Could I create a mixin or a true or false statement in SASS to unset a class that is gray to show the colour in its hovered or active state on the parent or something?
The tags are bootstrap.
<div class="row">
<div class="col-md-3">
<div class="sau-select selected">
<div class="header">
<h4>Self Managed</h4>
<p>label</p>
</div>
<div class="main">
<div class="tag tag-success">Success</div>
<p>Included</p>
</div>
</div>
</div><!-- /col-md-3 -->
<div class="col-md-3">
<div class="sau-select error">
<div class="header">
<h4>Self Managed</h4>
<p> </p>
</div>
<div class="main">
<span> </span>
<p>Included</p>
</div>
</div>
</div><!-- /col-md-3 -->
<div class="col-md-3">
<div class="sau-select">
<div class="header">
<h4>Self Managed</h4>
<p>label</p>
</div>
<div class="main">
<span class="tag tag-warning">Recommened</span>
<p><i class="fa fa-plus" aria-hidden="true"></i> $399.00</p>
</div>
</div>
</div><!-- /col-md-3 -->
<div class="col-md-3">
<div class="sau-select">
<div class="header">
<h4>Self Managed</h4>
<p>label</p>
</div>
<div class="main">
<span class="tag tag-success">Success</span>
<p>Included</p>
</div>
</div>
</div><!-- /col-md-3 -->
</div><!-- /row -->
SASS
.sau-select {
border: 2px solid $sau-gray-mid;
float:left;
width:100%;
text-align:center;
cursor:pointer;
.header{
background-color: $sau-gray-mid;
color:#fff;
padding:7px 0 7px 0;
h4{
font-size:1.1rem;
}
p{
font-size:0.8rem;
padding:0;
margin:-7px 0 0 0;
line-height:18px;
}
}
.main{
color:$sau-gray-mid;
padding:4px 0 15px 0;
p{
padding:0;
margin:0;
}
}
&:hover, &.selected{
border: 2px solid $sau-blue;
.header{
background-color: $sau-blue;
}
.main{
color:$sau-blue;
}
}
&.error{
border: 2px solid $brand-danger;
.header{
background-color: $brand-danger;
}
.main{
color:$brand-danger;
}
}
}
If I've read your question correctly, I think you may have a slightly wrong idea of what SASS does. I'll attempt to answer as best I can;
SASS is simply a sugar layer, no matter what function or mix-in you have in a sass file, it always ends up being compiled and being a .css file, Its ability to effect the browser is 100% limited to the exact standards of css, so if css can do it, it is possible, if css can't, sass will not help you.
So with this in mind, having color change on hover is no problem, and your code appears to suggest that you have already achieved this.
As for the selected color, there simply is no way around it, you must add the .selected class to the HTML. This will obviously trigger the color change from the associated class.
Hopefully my answer helps you.

CSS Selector :last-of-type + [attribute~=value] [duplicate]

<div class="commentList">
<article class="comment " id="com21"></article>
<article class="comment " id="com20"></article>
<article class="comment " id="com19"></article>
<div class="something"> hello </div>
</div>
I want to select #com19 ?
.comment {
width:470px;
border-bottom:1px dotted #f0f0f0;
margin-bottom:10px;
}
.comment:last-child {
border-bottom:none;
margin-bottom:0;
}
That does not work as long as I do have another div.something as actual last child in the commentList. Is it possible to use the last-child selector in this case to select the last appearance of article.comment?
jsFiddle
:last-child only works when the element in question is the last child of the container, not the last of a specific type of element. For that, you want :last-of-type
http://jsfiddle.net/C23g6/3/
As per #BoltClock's comment, this is only checking for the last article element, not the last element with the class of .comment.
body {
background: black;
}
.comment {
width: 470px;
border-bottom: 1px dotted #f0f0f0;
margin-bottom: 10px;
}
.comment:last-of-type {
border-bottom: none;
margin-bottom: 0;
}
<div class="commentList">
<article class="comment " id="com21"></article>
<article class="comment " id="com20"></article>
<article class="comment " id="com19"></article>
<div class="something"> hello </div>
</div>
I guess that the most correct answer is: Use :nth-child (or, in this specific case, its counterpart :nth-last-child). Most only know this selector by its first argument to grab a range of items based on a calculation with n, but it can also take a second argument "of [any CSS selector]".
Your scenario could be solved with this selector: .commentList .comment:nth-last-child(1 of .comment)
But being technically correct doesn't mean you can use it, though, because this selector is as of now only implemented in Safari.
For further reading:
https://drafts.csswg.org/selectors-4/#the-nth-child-pseudo
http://caniuse.com/#search=nth-child
If you are floating the elements you can reverse the order
i.e. float: right; instead of float: left;
And then use this method to select the first-child of a class.
/* 1: Apply style to ALL instances */
#header .some-class {
padding-right: 0;
}
/* 2: Remove style from ALL instances except FIRST instance */
#header .some-class~.some-class {
padding-right: 20px;
}
This is actually applying the class to the LAST instance only because it's now in reversed order.
Here is a working example for you:
<!doctype html>
<head><title>CSS Test</title>
<style type="text/css">
.some-class { margin: 0; padding: 0 20px; list-style-type: square; }
.lfloat { float: left; display: block; }
.rfloat { float: right; display: block; }
/* apply style to last instance only */
#header .some-class {
border: 1px solid red;
padding-right: 0;
}
#header .some-class~.some-class {
border: 0;
padding-right: 20px;
}
</style>
</head>
<body>
<div id="header">
<img src="some_image" title="Logo" class="lfloat no-border"/>
<ul class="some-class rfloat">
<li>List 1-1</li>
<li>List 1-2</li>
<li>List 1-3</li>
</ul>
<ul class="some-class rfloat">
<li>List 2-1</li>
<li>List 2-2</li>
<li>List 2-3</li>
</ul>
<ul class="some-class rfloat">
<li>List 3-1</li>
<li>List 3-2</li>
<li>List 3-3</li>
</ul>
<img src="some_other_img" title="Icon" class="rfloat no-border"/>
</div>
</body>
</html>
Something that I think should be commented here that worked for me:
Use :last-child multiple times in the places needed so that it always gets the last of the last.
Take this for example:
.page.one .page-container .comment:last-child {
color: red;
}
.page.two .page-container:last-child .comment:last-child {
color: blue;
}
<p> When you use .comment:last-child </p>
<p> you only get the last comment in both parents </p>
<div class="page one">
<div class="page-container">
<p class="comment"> Something </p>
<p class="comment"> Something </p>
</div>
<div class="page-container">
<p class="comment"> Something </p>
<p class="comment"> Something </p>
</div>
</div>
<p> When you use .page-container:last-child .comment:last-child </p>
<p> you get the last page-container's, last comment </p>
<div class="page two">
<div class="page-container">
<p class="comment"> Something </p>
<p class="comment"> Something </p>
</div>
<div class="page-container">
<p class="comment"> Something </p>
<p class="comment"> Something </p>
</div>
</div>
The new :has() pseudo class (not yet supported by all browsers) lets you get pretty close to a solution:
.class:has(+ :not(.class))
The limitation is that this will find any element with .class which is followed by an element that doesn't have this class. But this would match the use case of the question.
What about this solution?
div.commentList > article.comment:not(:last-child):last-of-type
{
color:red; /*or whatever...*/
}
This can now be solved with careful use of :has(), specifically:
/* switch out the {class} below */
.{class}:not(:has(~ .{class}))
A similar technique also allows you to select anything but the last occurrence of a class in a container, or the last occurrence within a group of elements. See the snippet below for examples.
Note: has() is currently supported in Chrome, Edge and Safari, but not Firefox (Jan 2022)
/* last in group */
.class:has(+ :not(.class)) {
background: pink;
}
/* anything but last in container */
.class:has(~ .class) {
box-shadow: 0 0 0 1px #F00A;
}
/* last in container */
.class:not(:has(~ .class)) {
background: #0F0A;
}
<div>
<div class="class">not-last</div>
<div class="class">not-last</div>
<div class="class">last-in-group</div>
<div>---</div>
<div class="class">not-last</div>
<div class="class">last-in-group</div>
<div>---</div>
<div class="class">last-class</div>
<div>---</div>
</div>
There are two ways to select the last element of a class.
Wrap your elements in a container element.
html:
<div class="container">
<div class="member">Member</div>
<div class="member">Member</div>
<div class="member">Member</div>
<div>
css:
.container:last-child {
color: red;
}
If you don't want to wrap your elements within another element then you can leverage last-of-type.
html:
<div class="member">Member</div>
<div class="member">Member</div>
<div class="member">Member</div>
css:
.member:last-of-type{
color: red;
}

float:right property on <p> which is inside a <div> is not working

I want to right align the number which is inside the tag which is again inside the tag.
<div class="first">
<a class="background-type1" >
<p>Some text</p>
<p class="pull-right">{{=val1}}</p>
</a><a class="background-type2">
<p>SOme other text</p>
<p class="pull-right">{{=val2}}</p>
</a>
</div>
css:
.pull-right {
float: right;
}
Need Help as what should I add to css so that so that val1and val 2 get right align to right of
Thanks in advance!
You could put the values inside a <span class="pull-right"> tag, like:
HTML:
<div class="first">
<a class="background-type1">
<p>Some text
<span class="pull-right">1</span>
</p>
</a>
<a class="background-type2">
<p>Some other text
<span class="pull-right">2</span>
</p>
</a>
</div>
CSS:
.pull-right {
float: right;
}
DEMO: http://jsfiddle.net/sJQu4/1/
The floated element needs to precede or be a child of the element you want it floated next to. You would be better off doing a float:left on the first paragraph given the current source order, or just moving the <p class="pull-right"> before the other <p> in the HTML.
You can do it like this: http://jsfiddle.net/62dDV/
.pull-right { float: right; }
.first{ border: 1px solid red; }
p{ border: 1px solid silver; display: inline-block; }
a{ border: 1px solid green; display: block; }

Resources