How to make Pseudo selector work with scss? - css

I have a parent div with class horizontalTab.Under that another div with attribute role as tablist. I'm targeting the child div like below but I don't see these styles. What am I doing wrong?
<div class="horizontalTab">
<div role='tablist'>
<div>....</div>
code here
</div>
</div>
My .scss files looks like below
.horizontalTab {
> div[role='tablist'] {
&:after {
background: #ebecf0;
content: '';
display: block;
height: 2px;
left: 0;
position: absolute;
right: 10px;
}
> .tab[aria-selected=true] {
box-shadow: inset 0 -5px 0 #137cbd;
}
}
}
without the horizontalTab selector it works.

Related

Sass how to use ampersand within :not() pseudo class to mean not having a parent class?

I need add a condition "not parent class" to the code but it is not working.
Below is what I've tried:
.display-download-icon {
&:not(.media-2 &){ // if it does not has a parent with .media-2 class
&:hover {
.image-overlay {
display: block;
opacity: 1;
z-index: 2;
}
}
}
}
But it translates into the CSS below:
.display-download-icon:not(.media-2 .display-download-icon):hover .image-overlay {
display: block;
opacity: 1;
z-index: 2;
}
The HTML structure is:
<div class="media-2">
<div class="display-download-icon">
<div class="image-overlay"></div>
</div>
</div>
Can you help?
Thanks
To begin with, we have to get some things straight. You probably misunderstood this article with the somewhat unfortunate title. Although CSS has a child selector, it lacks the possibility to select parents. As SASS is only a more convenient way to write CSS, SASS cannot have such a thing either. This said, let's move on to your question.
If I understand you correctly, you want to have the hover effect on the image-overlay element only if it is not contained in an element with the class media-2.
If that's the case, then you will have to change your approach.
First, define the normal behaviour, i.e the one that is expected for all the elements except the ones with the .media-2 class. Then define a new rule for the .media-2 class children.
SASS
.display-download-icon {
display: block; /* Just for the demo */
height: 100px; /* Just for the demo */
width: 100%; /* Just for the demo */
border: 1px solid black; /* Just for the demo */
margin-bottom: 10px; /* Just for the demo */
> .image-overlay {
display: block;
opacity: 1;
z-index: 2;
height: 100%; /* Just for the demo */
width: 100%; /* Just for the demo */
&:hover {
background: red; /* Just for the demo */
}
}
}
.media-2 .display-download-icon > .image-overlay:hover {
background: none; /* Just for the demo */
}
Snippet
Check this snippet for the functionality
.display-download-icon {
display: block;
height: 100px;
width: 100%;
border: 1px solid black;
margin-bottom: 10px;
}
.display-download-icon > .image-overlay {
display: block;
opacity: 1;
z-index: 2;
height: 100%;
width: 100%;
}
.display-download-icon > .image-overlay:hover {
background: red;
}
.media-2 .display-download-icon > .image-overlay:hover {
background: none;
}
<div class="media-1">
<div class="display-download-icon">
<div class="image-overlay"></div>
</div>
</div>
<div class="media-2">
<div class="display-download-icon">
<div class="image-overlay"></div>
</div>
</div>
<div class="media-3">
<div class="display-download-icon">
<div class="image-overlay"></div>
</div>
</div>
I hope that you get the idea.
All the "&" does is act as an alias for the preceding parent selector, which is why you are getting the compiled output you are (because of the "&" after the .media-2 classname) . You just need to remove the last "&" and it will compile fine.
.display-download-icon {
&:not(.media-2){ // removed the "&"
&:hover {
.image-overlay {
display: block;
opacity: 1;
z-index: 2;
}
}
}
}
The above with compile to
.display-download-icon:not(.media-2):hover .image-overlay {
display: block;
opacity: 1;
z-index: 2;
}
But you can also remove some of that nesting as well to make it more readable
.display-download-icon:not(.media-2):hover {
.image-overlay {
display: block;
opacity: 1;
z-index: 2;
}
}
Which will compile to the same output.
Sadly, there's no such thing as a parent selector in CSS, so this isn't really a Sass ampersand issue as much as a core behaviour of CSS.
You'll need to write a dedicated rule like this:
/* base icon styling */
.display-download-icon {
...
}
/* separate rule for parent case */
div:not(.media-2) {
.display-download-icon {
&:hover {
.image-overlay {
display: block;
opacity: 1;
z-index: 2;
}
}
}
}

What is the meaning of an ampersand in Less selectors?

I download a project, and in it there use less write the stylesheet.
And in the script code the name: own-space, and in the less code, there are &-btn-box, &-tra and &-input-identifycode-con selectors.
I have two questions:
I don't know the .own-space in less and the name: own-space's relationship.
and what's the meaning of &-btn-box, &-tra and &-input-identifycode-con there? what's the function of them?
My code is below:
<template>
<div>
.....
</div>
</template>
<script>
export default {
components: {
},
name: 'own-space',
data () {
...
};
},
methods: {
...
}
};
</script>
<style lang="less" rel="stylesheet/less">
...
.own-space {
&-btn-box {
margin-bottom: 10px;
button {
padding-left: 0;
span {
color: #2D8CF0;
transition: all .2s;
}
span:hover {
color: #0C25F1;
transition: all .2s;
}
}
}
&-tra {
width: 10px;
height: 10px;
transform: rotate(45deg);
position: absolute;
top: 50%;
margin-top: -6px;
left: -3px;
box-shadow: 0 0 2px 3px rgba(0, 0, 0, .1);
background-color: white;
z-index: 100;
}
&-input-identifycode-con {
position: absolute;
width: 200px;
height: 100px;
right: -220px;
top: 50%;
margin-top: -50px;
border-radius: 4px;
box-shadow: 0 0 2px 3px rgba(0, 0, 0, .1);
}
}
</style>
Less/Sass and other pre-processors let you write the CSS code with nested rules (besides other things like variables, mixins, and so on). So you don't have to write the full path like you do in CSS. You can just nest the style.
For example, you could have a structure like:
<parent>
<child>
<grandchild>
</grandchild>
</child>
</parent>
In plain CSS, to style every element you would write:
parent { styles }
parent child { styles }
parent child grandchild { styles }
With Less (and other preprocessors like SCSS) you can do the following
parent {
some parent styles
& child {
some child styles
& grandchild {
some grandchild styles
}
}
&:hover { hover styles on parent }
&:before { pseudo element styles }
}
etc.
So, the use of & can be to enable style writing for elements that are in a relationship with the parent element ( in your case the .own-space ).
btn-box , -tra , -input-identifycode-con are direct children of the own-space element, and button is child of btn-box , span is child of button, grandchild of btn-box and , grandgrandchild ( :) ) of the own-pace. Anyway, you get the ideea :)
For the specific question .own-space { &-btn-box { ... } } would mean that there is an element with class own-space-btn-box which most probably is a child of own-space but NOT necessarily ( see end of answer ). The HTML seems to be structured in a BEM style but not according to the documentation and rules. When using preprocessors for styling it is highly recommended to use the BEM naming strategy. Take a look at it.
For example, the current structure COULD look like:
Stack Snippets do not accept SCSS. You can check out a working example here
.own-space {
&-btn-box {
margin-bottom: 10px;
button {
padding-left: 0;
span {
color: #2D8CF0;
transition: all .2s;
}
span:hover {
color: #0C25F1;
transition: all .2s;
}
}
}
&-tra {
width: 10px;
height: 10px;
transform: rotate(45deg);
position: absolute;
top: 50%;
margin-top: -6px;
left: -3px;
box-shadow: 0 0 2px 3px rgba(0, 0, 0, .1);
background-color: white;
z-index: 100;
}
&-input-identifycode-con {
position: absolute;
width: 200px;
height: 100px;
right: -220px;
top: 50%;
margin-top: -50px;
border-radius: 4px;
box-shadow: 0 0 2px 3px rgba(0, 0, 0, .1);
}
}
<div class="own-space">
The SO snippet doesn't support CSS preprocessors.
Example purposes only
<div class="own-space-btn-box">
<button>Button</button>
<span>Some span</span>
</div>
<div class="own-space-tra">
Tra tra
</div>
<div class="own-space-input-identifycode-con">
identifycode
</div>
</div>
IMPORTANT when you see styles like these in most cases the elements ARE related but keep in mind when debugging other people's code that it's not always the case. They can be unrelated, e.g.
<element class="element"> .... </element>
<element2 class="element-element2"> .... </element2>
The SCSS could still look like this and have the same effect
.element {
styles
&-element2 {
styles
}
}
See example -> not related
Another example use of & would be in the case you have two elements with a common class and a specific class, e.g.
<element class="element specific1">....</element>
<element class="element specific2">....</element>
You can add common styles and specific styles all together like
.element {
/* common styles */
&.specific1 {
/* specific 1 styles */
}
&.specific2 {
/* specific 2 styles */
}
}
There are a lot of different uses for &. Read more:
the-sass-ampersand
Sass parent selector
LESS
BEM naming

Dynamically styling pseudo elements with angularjs

I have a div like below:
<div class="circle-icon"><span class="icon icon-loanaccount"></span></div>
and this div tag has the following styles:
.circle-icon {
background: #db552d none repeat scroll 0 0;
width: 50px;
&::after{
border-bottom: 5px solid #db552d;
content: "";
height: 0;
position: absolute;
}&:before{
border-bottom: 5px solid #db552d;
content: "";
height: 0;
}
}
how can I dynamically style border-bottom with angular, suppose that I have the color I want to use in scope.borderColor ?
ng-style is your friend here, see working link here.
$scope.bordercolor = "thick dotted #ff0000";
<div class="circle-icon" ng-style ="{'border-bottom': bordercolor}">
<span class="icon icon-loanaccount"></span>
</div>

Rating system using CSS (hover from left to right)

Is there a simple way to reverse the colour order when hovering?
Using this trick here I have the order right > left:
&:hover,
&:hover ~ button {
color: red
}
The fiddle with the right > left: https://jsfiddle.net/celio/Lowc1ruh/
Example with the left > right: https://css-tricks.com/examples/StarRating/
It is impossible for me to use float, position: absolute; and anything that changes the right order of my current html.
Plain CSS example:
button {
margin: 0;
padding: 5px;
border: none;
background: transparent;
display: inline-block;
}
button:before {
content: "⋆";
font-size: 5rem;
line-height: 1;
}
button:hover,
button:hover ~ button {
color: red;
}
<div class="wrapper">
<button></button>
<button id="2"></button>
<button></button>
<button></button>
<button></button>
</div>
One way would be to make all the child button elements color: red; when hovering over .wrapper. Then use the sibling selector (~) to change any elements after the currently hovered element to color: black;.
You should remove any whitespace between the elements (in this case I put them into one line in the HTML) to ensure that the cursor is always hovering over a star.
Example with plain CSS:
.wrapper button {
margin: 0;
padding: 5px;
border: none;
background: transparent;
display: inline-block;
}
.wrapper button:before {
content: "⋆";
font-size: 5rem;
line-height: 1;
}
.wrapper button:hover ~ button {
color: black;
}
.wrapper:hover button {
color: red;
}
<div class="wrapper">
<button></button><button id="2"></button><button></button><button></button><button></button>
</div>
JS Fiddle using SASS

Inherit CSS class from separate file?

I have a class for a button:
.client-header button {
/*Properties*/
}
and a class to detect when the menu is open:
.client-menu-open {
/*Properties*/
}
I would like to change the button background based on whether or not the menu is open. I want something like this:
.client-header button .client-menu-open {
/*Properties*/
}
But the classes are in two different files, so it doesn't work. Is there any way to do this across different files?
Here is the code for the header index.css:
#import url('../menu/index.css');
.client-header {
position: absolute;
top: 0;
left: 0;
right: 0;
height: var(--header-height);
overflow: hidden;
border-bottom: 1px solid #7E7E7E;
background: #cccccc;
}
.client-header button {
float: left;
height: 100%;
border: none;
border-right: 1px solid var(--border-color);
border-radius: 0;
box-shadow: none;
line-height: 39px;
background-color: #444444;
color: #FFF;
}
.client-header button:hover {
background-color: #555555;
}
.client-header button:active {
background-color: #4E4E4E;
}
.client-header-caption {
float: left;
}
.client-header-title,
.client-header-subtitle {
margin-left: 10px;
}
.client-header-title {
line-height: 25px;
}
.client-header-subtitle {
font-size: 0.5rem;
line-height: 15px;
}
#media (min-width: 640px) {
.client-header-title,
.client-header-subtitle {
display: inline-block;
line-height: var(--header-height);
}
.client-header-title {
font-size: 1.5rem;
}
.client-header-subtitle {
font-size: 1rem;
}
}
.client-header .client-menu-open button {
background: #CCCCCC;
}
And here is the code for the menu index.css:
.client-menu {
position: absolute;
top: var(--header-height);
bottom: 0;
left: -var(--menu-width);
width: var(--menu-width);
border-right: 1px solid var(--border-color);
padding-bottom: var(--menu-footer-height);
overflow: hidden;
transition: left 0.2s;
}
.client-menu-open {
left: 0;
box-shadow: 0 0 30px var(--shadow-color);
background: #444444;
}
.client-menu-pinned {
box-shadow: none;
}
.client-menu-header {
height: var(--menu-header-height);
text-align: right;
background-color: #444444;
}
.client-menu-footer {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: var(--menu-footer-height);
text-align: right;
}
And the HTML structure is:
<header class="client-header">
<button class="client-header-menu-toggle"/>
</header>
<div class="client-menu"/>
You can use #import like so (in your primary CSS stylesheet):
#import url('external.css');
/* external.css above will be loaded */
Refer to this documentation: http://www.cssnewbie.com/css-import-rule/
Link to the other file and style .client-menu-open
if this is your html
<div class="client-menu-open"> <!-- this class is here only if the menu gets opened, else, this div has no class -->
stuff
stuff
<div class="client-header-button">
<button></button>
</div>
</div>
the correct syntax is the following
button {
background:red;
}
.client-menu-open button {
background:blue
}
The #import rule allows you to include external style sheets in your document. It is a way of creating a style sheet within your document, and then importing additional rules into the document.
To use the #import rule, type:
<style type="text/css">
#import url("import1.css");
#import url "import2.css";
</style>
For more info refer here https://developer.mozilla.org/en-US/docs/Web/CSS/#import
your CSS selector is incorrect, that's why it doesn't work. It has nothing to do with where CSS styles are defined.
.client-header button .client-menu-open will only select the following elements:
elements with class="client-menu-open"
which are children of button elements
which themselves are children of elements with class="client-header"
.
what you want, I think, is
button elements
which are children of elements having "class=client-header" AND "class=client-menu-open".
the proper selector for those elements would be .client-header.client-menu-open button.

Resources