Nesting with two levels in scss not working - html

Let's say I have a page which displays emotion and the corresponding text for it.
I wanted to change color of text based on the type of emotion. I've followed nesting inside text class but that didn't apply the styles mentioned for the text alone. Is there any way to do this?
.emotion{
display: flex;
&__text {
outline: 1px solid blue; // Not applied
&--happy{
color: rebeccapurple
}
&--sad{
color: yellow
}
}
}
<div class="emotion">
<span class="emotion__text--happy">
Happy
</span>
<!-- <span className="emotion__text__sad"></span>
<span className="emotion__text__tears"></span>
<span className="emotion__text__joy"></span> -->
<span class="emotion__happy">
😀
</span>
</div>

Your SCSS:
.emotion { &__text { outline: 1px solid blue; } }
means the same as this CSS:
.emotion__text { outline: 1px solid blue; }
And the class selector .emotion__text means:
✅ Elements which are members of the emotion__text class.
You don't have any elements that match.
You have an element with class="emotion" and one with class="emotion__text--happy" but not class="emotion__text"
It doesn't mean:
❌ Elements which are members of any class which starts with emotion__text.
You could add that class to an element:
class="emotion__text emotion__text--happy"

Related

How to not execute parent's :hover on child :hover

When the .post-item <div> is hovered I want to execute some specific styles (change background-color and cursor) but I don't want this to happen if the .rating-wrapper <div> is hovered too. This happens because I want the .rating-wrapper to do something different than the hover of its parent. Basic question: How to do only child's hover, ignoring the parent's hover
HTML:
<div class="post-item">
<div class="rating-wrapper">
<div class="upvote">
<img src="/images/upvote_arrow.png" alt="upvote" />
</div>
<div class="rating"></div>
<div class="downvote">
<img src="/images/downvote_arrow.png" alt="downvote" />
</div>
</div>
<span class="owner-data">
<img src="" alt="" class="owner-avatar" />
<span class="owner-username"></span>
</span>
<span class="creation-date"></span>
<div class="title"></div>
</div>
Since you want to change the style of the parent element based on a pseudo-class of the child element, this isn't really possible with CSS alone today.
You can do it with the :has() pseudo-class but that is currently only supported in Safari (with support for Chrome a few months away and no sign of it in Firefox, Edge, Opera or elsewhere).
#parent {
background: white;
border: solid black 1px;
padding: 2em;
max-width: 50%;
margin: auto;
}
#parent:hover:not(:has(#child:hover)) {
background: orange;
}
#child {
background: #aaa;
border: solid black 1px;
padding: 2em;
}
#child:hover {
background: green;
}
<div id="parent">
<div id="child"></div>
</div>
For a more reliable approach, you should probably look at adding a splash of JavaScript to the mix.
Use mouseenter and mouseleave events to modify the classes of the parent element, then reference the class in your stylesheet.
const parent = document.querySelector('#parent');
const child = document.querySelector('#child');
const enter = event => parent.classList.add('child-hover');
const leave = event => parent.classList.remove('child-hover');
child.addEventListener('mouseenter', enter);
child.addEventListener('mouseleave', leave);
#parent {
background: white;
border: solid black 1px;
padding: 2em;
max-width: 50%;
margin: auto;
}
#parent:hover:not(.child-hover) {
background: orange;
}
#child {
background: #aaa;
border: solid black 1px;
padding: 2em;
}
#child:hover {
background: green;
}
<div id="parent">
<div id="child"></div>
</div>
You can use this CSS Selector,
.post-item>:not(.rating-wrapper):hover {
background-color: white;
}
This will select all immediate children of .post-item which are not .rating-wrapper.
To change the block of the remaining items background color, you can enclose them in another div.
There is a css property called not property.The syntax is like:
:not(element) {
// CSS Property}
If you want to learn more, please visit this link:
https://www.geeksforgeeks.org/how-to-exclude-particular-class-name-from-css-selector/
The pointer-events CSS property sets under what circumstances (if any) a particular graphic element can become the target of pointer events.
try:
pointer-events: none
you can read more here: https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events

Change background for first child using CSS

I have this html markup which I can't change due to my theme.
<div class="x-breadcrumb-wrap">
<div class="x-container max width">
<div class="x-breadcrumbs"><span class="home"><i class="x-icon-home" data-x-icon=""></i></span> <span class="delimiter"><i class="x-icon-angle-right" data-x-icon=""></i></span> Guides <span class="delimiter"><i class="x-icon-angle-right" data-x-icon=""></i></span> <span class="current"> london <span class="delimiter"><i class="x-icon-angle-right" data-x-icon=""></i></span> <span class="current">Stays <span class="delimiter"><i class="x-icon-angle-right" data-x-icon=""></i></span> <span class="current">Venue</span></div>
</div>
</div>
I am trying to remove the background for the first:child (i.e. home icon) but using the code below the background is removed for subsequent links in the breadcrumbs.
.x-breadcrumb-wrap a {
color: #ffffff !important;
background: #2b2b2b;
padding: 1px 6px 1px 6px;
text-shadow: none !important;
letter-spacing: 0.13em;
border-radius: 3px;
}
.x-breadcrumb-wrap a:first-child {
background: transparent;
}
any ideas ?
Your selector isn't working as expected because it is selecting all of the descendant a elements that are a first child.
You need to use the direct child selector, >, in order to only target the direct child a element of the .x-breadcrumbs element. In doing so, only the first child in the .x-breadcrumbs element is selected rather than all of the descendant elements that happen to be the first child of their parent element.
.x-breadcrumb-wrap .x-breadcrumbs > a:first-child {
background: transparent;
}

Using Nth-Child With Span Elements - All Span Elements Are Odd For Some Reason

I'm trying to use the nth-child pseudo selector to target even an odd spans in a containing div. My HTML markup looks like this.
<div class="load-data">
<span>Company: Heavy Haul LLC.</span><br>
<span>Name: John Smith</span><br>
<span>Phone: (123)-456-7890</span><br>
<span>Position: Chase</span><br>
<span>From: Knoxville, TN</span><br>
<span>To: Nashville, TN</span><br>
<span>Date: 03/02/2016</span><br>
<span>Rate: $250 Day Rate</span><br>
</div>
And my CSS looks like this:
.load-data {
border: 1px solid #454545;
background-color: #121212;
display: inline-block;
margin: 5px 10px;
text-align: left;
}
.load-data > span {
padding: 5px;
display: inline-block;
}
.load-data span:nth-child(even) {
color: #ff6400;
}
.load-data span:nth-child(odd) {
color: #ff9900;
}
But for some reason every span element has the color of ff9900. Why would they all be odd numbers?
For debugging I did try using nth-child(5) just to see what happens and the third line was selected for some reason instead of the fifth one.
I'm not understanding why this is happening.
Choices
Use nth-of-type instead, It's counting <br> as a child.
Use nth-child and div instead of span and get rid of the <br>.
If you simply remove the <br> and use nth-child you'll get a mess since <span> are inline, see second example.
At that point you either change the<span> by assigning this to your CSS:
span { display: block; }
Or change <span> into <div>
Snippet
.load-data span:nth-of-type(even) { background: blue; }
.load-data span:nth-of-type(odd) { background: red; }
.x span:nth-child(even) { background: blue; }
.x span:nth-child(odd) { background: red; }
<div class="load-data">
<span>Company: Heavy Haul LLC.</span><br>
<span>Name: John Smith</span><br>
<span>Phone: (123)-456-7890</span><br>
<span>Position: Chase</span><br>
<span>From: Knoxville, TN</span><br>
<span>To: Nashville, TN</span><br>
<span>Date: 03/02/2016</span><br>
<span>Rate: $250 Day Rate</span><br>
</div>
<br><br>
<div class="x">
<span>Company: Heavy Haul LLC.</span>
<span>Name: John Smith</span>
<span>Phone: (123)-456-7890</span>
<span>Position: Chase</span>
<span>From: Knoxville, TN</span>
<span>To: Nashville, TN</span>
<span>Date: 03/02/2016</span>
<span>Rate: $250 Day Rate</span>
</div>

Separators between elements without hacks

One thing I often want to do when laying out a website is to have some elements next to each other, with separators between them. For instance, if I have three elements, I'd want two separators between them, and nothing at either end.
I achieve this in various ways. For vertical stacking of elements, I sometimes use <hr />. Horizontally, I might do something like:
<div>
<span class="notend">things</span>
<span class="notend">stuff</span>
<span>items</span>
</div>
.notend {
border-right: solid black 1px;
}
Is there a more semantic way of doing this? I want to have separators between elements without putting styling elements into the HTML part, or using non-semantic classes. I don't mind of this requires hacky CSS, I just want to get stuff to do with styling away from the HTML files.
Use this:
#menu span + span {
border-left: solid black 1px;
}
http://jsfiddle.net/thirtydot/QxZ6D/
That will apply border-left to all except the first span.
The adjacent sibling selector (+) is supported in all modern browsers except IE6.
Another way to do it is this, which is sometimes nicer because you can keep all the declarations for the "menu buttons" in one block:
http://jsfiddle.net/thirtydot/QxZ6D/1/
#menu span {
border-left: solid black 1px;
/*
a: bunch;
of: stuff;
*/
}
#menu span:first-child {
border-left: 0
}
This has exactly the same level of browser support as the first solution.
Note that if you like this solution, it's better to use :first-child rather than :last-child, because :first-child (from CSS2) is supported in IE7/8 and :last-child (only introduced in CSS3!) isn't.
you can do like this also:
span {position:relative; margin-left:5px}
span:after {
content:"|";
position:absolute;
left:-5px;
}
span:first-child:after {
content:"";
}
In this method you can also use others separators like / , \ , .
http://jsfiddle.net/sandeep/UNnxE/
how about something like this in your example:
<div>
<span>things</span>
<span>stuff</span>
<span>items</span>
</div>
div span{
border-left: solid black 1px;
}
div span:last-child{
border:none;
}
no need for additional classes.
Well for a start, you can simplify it to this:
<div>
<span>things</span>
<span>stuff</span>
<span class="end">items</span>
</div>
span {
border-right: solid black 1px;
}
span.end {
border-right: none;
}
If you're willing to drop some support in older browsers, you can reduce that to this, using the :last-child pseudo-class:
<div>
<span>things</span>
<span>stuff</span>
<span>items</span>
</div>
span {
border-right: solid black 1px;
}
span:last-child {
border-right: none;
}
I often want to have a series of items with semi-colons between them.
Here's what I do for this:
.semi-list span:not(:last-of-type)::after {
content: "; ";
}
<div class="semi-list">
<span>Item One</span>
<span>Item Two</span>
<span>Item Three</span>
</div>
It's a pretty flexible solution.
Ref:
https://www.w3schools.com/cssref/sel_not.asp
https://www.w3schools.com/csSref/sel_last-of-type.asp
Something like this?
CSS:
#note_list span {
display:inline-block;
padding:0 10px;
}
.notend {
border-right:1px solid #000000;
}
HTML:
<div id="note_list">
<span class="notend">things</span>
<span class="notend">stuff</span>
<span>items</span>
</div>

Remove ':hover' CSS behavior from element

I have CSS that changes formatting when you hover over an element.
.test:hover { border: 1px solid red; }
<div class="test">blah</div>
In some cases, I don't want to apply CSS on hover. One way would be to just remove the CSS class from the div using jQuery, but that would break other things since I am also using that class to format its child elements.
Is there a way to remove 'hover' css styling from an element?
One method to do this is to add:
pointer-events: none;
to the element, you want to disable hover on.
(Note: this also disables javascript events on that element too, click events will actually fall through to the element behind ).
Browser Support ( 98.12% as of Jan 1, 2021 )
This seems to be much cleaner
/**
* This allows you to disable hover events for any elements
*/
.disabled {
pointer-events: none; /* <----------- */
opacity: 0.2;
}
.button {
border-radius: 30px;
padding: 10px 15px;
border: 2px solid #000;
color: #FFF;
background: #2D2D2D;
text-shadow: 1px 1px 0px #000;
cursor: pointer;
display: inline-block;
margin: 10px;
}
.button-red:hover {
background: red;
}
.button-green:hover {
background:green;
}
<div class="button button-red">I'm a red button hover over me</div>
<br />
<div class="button button-green">I'm a green button hover over me</div>
<br />
<div class="button button-red disabled">I'm a disabled red button</div>
<br />
<div class="button button-green disabled">I'm a disabled green button</div>
Use the :not pseudo-class to exclude the classes you don't want the hover to apply to:
FIDDLE
<div class="test"> blah </div>
<div class="test"> blah </div>
<div class="test nohover"> blah </div>
.test:not(.nohover):hover {
border: 1px solid red;
}
This does what you want in one css rule!
I would use two classes. Keep your test class and add a second class called testhover which you only add to those you want to hover - alongside the test class. This isn't directly what you asked but without more context it feels like the best solution and is possibly the cleanest and simplest way of doing it.
Example:
.test { border: 0px; }
.testhover:hover { border: 1px solid red; }
<div class="test"> blah </div>
<div class="test"> blah </div>
<div class="test testhover"> blah </div>
add a new .css class:
#test.nohover:hover { border: 0 }
and
<div id="test" class="nohover">blah</div>
The more "specific" css rule wins, so this border:0 version will override the generic one specified elsewhere.
I also had this problem, my solution was to have an element above the element i dont want a hover effect on:
.no-hover {
position: relative;
opacity: 0.65 !important;
display: inline-block;
}
.no-hover::before {
content: '';
background-color: transparent;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 60;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<button class="btn btn-primary">hover</button>
<span class="no-hover">
<button class="btn btn-primary ">no hover</button>
</span>
You want to keep the selector, so adding/removing it won't work. Instead of writing a hard and fast CSS selectors (or two), perhaps you can just use the original selector to apply new CSS rule to that element based on some criterion:
$(".test").hover(
if(some evaluation) {
$(this).css('border':0);
}
);