I'm trying to target an inner element with Sass using the :hover selector, but for some reason when using the partial selector with the underscore, the property gets ignored. The only workaround is to type the entire class name:
HTML:
<div class="cds__grid">
<div class="cds__card">
<img src="images/content/image.svg">
<div class="cds__card-overlay">
<h4>A Title</h4>
<p>Some Text</p>
</div>
</div>
</div>
SCSS:
.cds{
&__grid{
//Some Properties
}
&__card{
&-overlay{
background-color: grey;
}
&:hover{
//Ignored
&-overlay{
background-color: blue;
}
//Applied on Hover
.cds__card-overlay{
background-color: blue;
}
}
}
}
Here is the solution, you need to add & after hover to keep reference of the parent class
CodePen Link
.cds{
&__grid{
//Some Properties
}
&__card{
&-overlay{
background-color: grey;
}
&:hover &{
// Ignored
&-overlay{
background-color: blue;
}
}
}
}
<div class="cds__grid">
<div class="cds__card">
<img src="images/content/image.svg">
<div class="cds__card-overlay">
<h4>A Title</h4>
<p>Some Text</p>
</div>
</div>
</div>
To understand why this is ignored it helps to learn more about the ampersand in SCSS.
This is not some magic tool that sorts selectors, it just inserts the parent at the point where you write the &.
So if you write something like this:
.class {
&:hover {
&-detail {
}
}
}
This will be compiled into this:
.class {}
.class:hover {}
.class:hover-detail {}
Note the last selector, this is not a valid CSS selector, so this is why it get's ignored.
To achieve something like .class-detail:hover you would have to do something like this:
.class {
&:hover {
}
&-detail {
&:hover {
}
}
}
You simply missed a } at the end of your code, and also an & sign to refer to your original element.
See in codepen.io: https://codepen.io/basescriptnet/pen/KKqWweo
.cds{
&__grid {
//Some Properties
}
&__card{
&-overlay {
background-color: grey;
}
&:hover &{
//Ignored
&-overlay {
background-color: blue;
}
//Applied on Hover
.cds__card-overlay {
background-color: blue;
}
}
}
}
<div class="cds__grid">
<div class="cds__card">
<img src="images/content/image.svg">
<div class="cds__card-overlay">
<h4>A Title</h4>
<p>Some Text</p>
</div>
</div>
</div>
Update. I missed & sign after :hover, which led to wrong execution of the code. Instead of referring to parent, it was referring to .cds__card:hover-overlay.
Related
I'm really new to HTML and CSS and I have just studied nesting where I've got an issue with one of the css challenges for beginners.
Here are the challenge requirements:
to make the word (title) red.
to make the word (child title) blue.
to make the word (paragraph content) green.
to make the word (section title) green too.
I was already gives the HTML code and as per the requirements I MUST NOT make any change in it.
div div span {
color: red;
}
div span {
color: blue;
}
p {
color: green;
}
<div class="parent">
<div class="child">This Is Child <span class="title">Title</span></div>
<span class="title">Child Title</span>
<p>Paragraph Content</p>
</div>
<div class="title">Section Title</div>
Kindly assist with number 4. Thank you very much in advance.
Can take note of this CSS for all requirements.
> = child selector
~ = sibling selector
, = comma represents styles for both elements separately
.parent>.child>span {
color: red;
}
.parent>.child~.title {
color: blue;
}
.parent>p,
.title {
color: green;
}
<div class="parent">
<div class="child">This Is Child <span class="title">Title</span></div>
<span class="title">Child Title</span>
<p>Paragraph Content</p>
</div>
<div class="title">Section Title</div>
Change your CSS to
div div span {
color: red;
}
div span {
color: blue;
}
p {
color: green;
}div {
color: green;
}
I would like to force a specific attribute on children elements, from the level of the parent. I thought that using !important would be enough, but it is not taken into account on children elements:
.up {
color: red !important;
}
.down {
color: blue;
}
<div class="up">
<div class="down">
this text should be red
</div>
</div>
Is it possible to cascade !important down to the children elements?
You can do the following:
.up > * {
color: red !important;
}
This will affect all direct child elements. (You could probably erase the !important in this case, but that depends on the order of the rules and on theselector specifity of the rules for the child elements)
If you want to apply it to ALL children (not just the direct ones), use it without the >, like
.up * {
color: red !important;
}
.down {
color: blue;
}
.up > * {
color: red;
}
<div class="up">
<div class="down">
this text should be red
</div>
</div>
Please try this
.up>.down {
color: red;
}
I hope this is the solution that what you looking for.
.up > .down {
color: red;
}
.down {
color: blue;
}
If u add the html like below the code and ur css will be correct..
HTML:
<div class="up">
this text should be blue
<div class="down">
this text should be red
</div>
</div>
Or Do u want the reverse color then, change the css code
css
.up {
color: blue !important;
}
.down {
color: red;
}
<div class="up myclass">
<div class="down">
this text should be red
</div>
</div>
.up {
color: red !important;
}
.down {
color: blue;
}
.myclass .down {color:initial; color:inherit;}
Whenever you have this kind of situation if you are working other person's code then never edit the initial code because you never know what that code is working for. In this situation you need to do is create your own class and edit the children with your own class.
If you can change the CSS anyway, you can do this without needing !important.
.up {
color: red;
}
:not(.up) > .down {
color: blue;
}
<div class="up">
<div class="down">
this text should be red
</div>
</div>
<div class="down">
this text should be blue
</div>
Mechanism I have to work with, that is not changable:
Page is rendered with some styles on them eg. class xy.
Some html is generated dynamically and injected into:
<div id="InternalContent"> /* injected here */ </div>
by CSS is applied by doing:
#InternalContent {
/* .less files here */
}
The goal is to be able to render some elements inside #InternalContent with original classes, not overwritten by #InternalContent.
I tried:
#InternalContent:not(.NotInherited) { ... }
#InternalContent:not(*:not(.NotInherited)) { ... }
and some others, but to no success.
The only way this works is if the classes themself have :not(.NotInherited).
#InternalContent .xy:not(.NotInherited) { }
but in my case there are far to many classes to change manually for this to be an acceptable solution.
Smallest (not) working example:
https://jsfiddle.net/nvhouq1k/
HTML:
<p class="xy">This to be orange</p>
<div id="InternalContent">
<p class="xy">This to be blue</p>
<div class="NotInherited">
<p class="NotInherited xy">This to be orange</p>
</div>
</div>
CSS:
.xy {
color: orange;
}
#InternalContent:not(*:not(.NotInherited)) .xy{
color: blue;
}
/* *:not(.NotInherited) */
/* :not(.NotInherited) */
Change the order of your not() selector so that it only targets .xy elements: You can try the following:
.xy {
color: orange;
}
#InternalContent .xy:not(.NotInherited) {
color: blue;
}
<p class="xy">This to be orange</p>
<div id="InternalContent">
<p class="xy">This to be blue</p>
<div class="NotInherited">
<p class="NotInherited xy">This to be orange</p>
</div>
</div>
Is there a way to avoid the "red highlight" in the last example?
Live Demo
<h3>should be:</h3>
<div class="demo">
<p>foo foo</p>
<p>bar bar</p>
</div>
<hr>
<div class="demo">
<p>foo foo<br>foo foo</p>
<p>bar bar</p>
</div>
<hr>
<div class="demo">
<p>foo foo<br>foo foo</p>
</div>
<h3>should not be:</h3>
<div class="demo">
<p>foo foo</p>
</div>
This is what I currently use:
.demo p:first-child::first-line {
color: red;
}
But, it highlights all examples, including the last one. I also tried these two:
.demo p:first-child::first-line:not(:only-child) {
color: red;
}
/* and... */
.demo p:first-child::first-line:not(:only-of-type) {
color: red;
}
But it seems it just brokes all the highlight in all demos.
Is there way to achieve the desired result? (Remove "red highlight" from the last example).
(JS/jQuery solution is also ok, but, if it could be solved with CSS, it would be much better).
Screenshot with desired result:
I have a solution in jQuery.
CSS:
.demo p:first-child:first-line {
color: red;
}
.demo .not-red:first-line {
color: green !important;
}
JS:
$('.demo p:only-child:not(:has(br))').each(function() {
$(this).addClass('not-red');
});
JS will add not-red class only to paragraphs that doesn't contain br tags and paragraphs that are only child.
CODEPEN
One way to achieve this is to set the color on :first-child and then override with :only-child:
.demo p:first-child::first-line {
color: red;
}
.demo p:only-child, .demo p:only-child::first-line {
color: inherit;
}
Example: https://jsfiddle.net/4s42cnrL/4/
please use
.demo:not(:last-of-type) p:first-child::first-line {
color: red;
}
https://jsbin.com/doqenagapa/4/edit?html,css,output
Why "zawartosc prawo" do not hide "zawartosc lewo"? on hover effect?
I try change class name, add ID, and another, but still do not work :(
Maybe I must try add some JS? But I think someone know how to do this.
Code
.zamieniamlewo {
display: none;
}
.prawo:hover ~ .zamieniamlewo {
display: block !important;
}
.lewo:hover ~ .prawo {
display: none;
}
.zamieniamprawo {
display: none;
}
.lewo:hover ~ .zamieniamprawo {
display: block !important;
}
.lewo {
background: red;
padding: 20px;
}
.prawo {
background: green;
padding: 20px;
}
<div class="lewo">
<h3>Zawartość lewo</h3>
</div>
<div class="prawo">
<h3>Zawartość prawo</h3>
</div>
<div class="zamieniamlewo">
<h3 class="imie">zamieniamlewo</h3>
</div>
<div class="zamieniamprawo">
<h3>zamieniam prawo</h3>
</div>
The ~ combinator separates two selectors and matches the second element only if it is preceded by the first, and both share a common parent.
for example:
.red ~ p{
color:red;
}
<p>i m not red</p>
<p class='red'>i m not red</p>
<p>i m red</p>
<p>i m red</p>
here the last two paragraphs match the sibling selector.
So in your code you can change something like
<div class="prawo">
<h3>Zawartość prawo</h3>
</div>
<div class="lewo">
<h3>Zawartość lewo</h3>
</div>
and add this in .css file
.prawo:hover ~ .lewo {
display:none;
}
I guess you need some thing like this , i have used jquery as it seems pretty straight forward to use when you usually deal with events
$(document).ready(function(){
$(".lewo").mouseenter(function(){
$(".prawo").hide();
});
$(".lewo").mouseleave(function(){
$(".prawo").show();
$(".lewo").show();
});
$(".prawo").mouseenter(function(){
$(".lewo").hide();
});
$(".prawo").mouseleave(function(){
$(".prawo").show();
$(".lewo").show();
});
});
.zamieniamlewo {
display: none;
}
.zamieniamprawo {
display: none;
}
.lewo:hover ~ .zamieniamprawo {
display: block !important;
background:white;
}
.prawo:hover ~ .zamieniamlewo {
display: block !important;
background: white;
}
.lewo {
background: red;
padding: 20px;
}
.prawo {
background: green;
padding: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="lewo">
<h3>Zawartość lewo</h3>
</div>
<div class="prawo">
<h3>Zawartość prawo</h3>
</div>
<div class="zamieniamlewo">
<h3 class="imie">zamieniamlewo</h3>
</div>
<div class="zamieniamprawo">
<h3>zamieniam prawo</h3>
</div>