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
Related
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.
I have a project made with react and I want to optimize the css.
I have this code:
.class-1 {
margin-top: 15px;
}
.class-2 {
margin-bottom: 15px;
}
Is there a possible way to optimize like this during the build?
.class-3 {
margin: 15px 0 15px 0;
}
You can add both classes to your HTML element or combine the margins into one class like this:
.class1 {
margin-top: 15px;
background-color: skyblue;
}
.class2 {
margin-bottom: 15px;
}
.class3 {
margin: 15px 0;
background-color: red;
}
<div class='class1 class2'>My element with 2 classes</div>
<div class='class3'>My element with 1 class</div>
It all depends if you want to keep the classes separate for other areas of your code, or if you will never need those margins in separate classes.
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;
}
}
}
}
I would like to set some sibling classes in on hover action and I do it this way:
.div-inside-1:hover ~ .div-inside-tran-1{
left: 0px;
top: 0px;
opacity: 0%;
}
.div-inside-1:hover ~ .div-inside-tran-1::after{
background-color: rgba(0,0,0, .1);
}
Can I do it without copying and pasting the .div-inside-1:hover? One more thing is that how to set properties in ::after by hover in other class?
Thank you very much!
Edited:
Please refer to https://jsfiddle.net/k6ws0j9t/
Yes You can do in Sass like this
.div-inside-1 {
&:hover {
~ .div-inside-tran-1 {
left: 0px;
top: 0px;
opacity: 0%;
&::after {
background-color: rgba(0,0,0, .1);
}
}
}
}
Setting properties of ::after pseudo code on hover of some else class like this
.class{
&hover{
.class2{
&::after{
content:'';
background: none;//Your properties
}
}
}
}
Remember this can be done only if relation is parent child class, you
cant target parent by child trough css for that you need JavaScript
I am writing a mixin in Less that adds a play button to video tags. It looks like this:
.playVideoButton(#size: 64px) {
&:before {
content: "";
width: #size;
height: #size;
top: 50%;
left: 50%;
display: none;
position: absolute;
.transform(translate(-50%, -50%));
.border-radius(50%);
border: 2px solid #fff;
background-color: rgba(0, 0, 0, 0.35);
}
&:after {
width: 0;
height: 0;
content: "";
border-top: #size / 4 solid transparent;
border-bottom: #size / 4 solid transparent;
border-left: #size / 2.4 solid #fff;
top: 50%;
left: 50%;
display: none;
position: absolute;
.transform(translate(-35%, -50%));
}
&:hover {
&:before {
display: block;
&:hover {
background-color: rgba(0, 0, 0, 0.60);
}
}
&:after {
display: block;
}
}
}
It Works fine but I want to make a second hover effect for the :before. So I write at the end: &:hover > &:before > &:hover {background-color: rgba(0, 0, 0, 0.60);} but when I hover the :before element I don't get a change of the background opacity.
Chromes Dev Tool hides the hover settings for pseudo elements. So is it not possible to modify them without JavaScript?
At present you can't attach :hover (or any other pseudo-classes to a pseudo-element). It is implied by the below text in the W3C Spec for pseudo-elements:
Only one pseudo-element may appear per selector, and if present it must appear after the sequence of simple selectors that represents the subjects of the selector.
and the following one from the W3C Spec for selector syntax:
One pseudo-element may be appended to the last sequence of simple selectors in a selector.
Pseudo-classes (like :hover, :link etc) are simple selectors and a pseudo-element can only be appended after all such simple selectors. So, it rules out the possibility of a div:hover:before:hover or div:before:hover.
In the below snippet, a very simple one, you can see how the div:after:hover selector never gets matched while the div:hover:after does.
div:after {
display: block;
content: 'World';
background: beige;
}
div:after:hover {
background: green;
}
div:hover:after {
border: 1px solid green;
}
div:hover {
border: 1px solid red;
}
<div>Hello!</div>
You should consider creating that play button using an actual child element (instead of a pseudo) and then attach the :hover selector to it.