scss how to reuse inner selector? - sass

I have code like this:
.outer1 {
&.same-inner {
background-color: white;
}
}
.outer2 {
&.same-inner {
background-color: white;
}
}
.outer3 {
&.same-inner {
background-color: white;
}
}
How do I reuse .same-inner selector?

.outer1, .outer2, .outer3 {
&.same-inner {
background-color: white;
}
}
Translates to CSS:
.outer1.same-inner, .outer2.same-inner, .outer3.same-inner {
background-color: white;
}
Or if you wanted to give each of the outer's there own properties, but also inherit same-inner
.same-inner {
background-color: white;
}
.outer1 {
width:10px;
#extend .same-inner
}
.outer2 {
width:20px;
#extend .same-inner
}
.outer3 {
width:30px;
#extend .same-inner
}
Translates to CSS:
.same-inner, .outer1, .outer2, .outer3 {
background-color: white;
}
.outer1 {
width: 10px;
}
.outer2 {
width: 20px;
}
.outer3 {
width: 30px;
}
Or maybe what you want is:
.same-inner {
background-color: white;
&.outer1 {
width:10px;
#extend .same-inner
}
&.outer2 {
width:20px;
#extend .same-inner
}
&.outer3 {
width:30px;
#extend .same-inner
}
}
Which churns out CSS:
.same-inner, .same-inner.outer1, .same-inner.outer2, .same-inner.outer3 {
background-color: white;
}
.outer1.same-inner {
width: 10px;
}
.outer2.same-inner {
width: 20px;
}
.outer3.same-inner {
width: 30px;
}

You can reuse a selector by #extend.
follow this sass documentation about #extend.

Related

One shared selector between multiple classes

How to apply the same focus state to multiple different classes?
Problem:
.btn {
&.error {
border-color: red;
}
&.primary {
border-color: green;
}
&:focus {
border-color: blue;
// this is not applied but i don't want to
// declare the same style to both classes
}
}
I understand this would be one option, but it is also not the prettiest option as i need to list them separately here
.btn {
&.error {
border-color: red;
}
&.primary {
border-color: green;
}
&.primary:focus, &.error:focus {
border-color: blue;
}
}
Are there any better ways?
Using & again in the nested rule is a good way for your purpose.
.btn {
&.error {
border-color: red;
}
&.primary {
border-color: green;
}
&.primary, &.error {
&:focus{
border-color: blue;
}
}
}

How to use last:child?

I'm working with sass, and my code doesn't work.
I would like to take off the last ":after" (pipe) but I can't.
Thank You
.l-footer-top {
.nav {
a {
color: $green;
padding: 0rem 0.5rem;
text-transform: uppercase;
&:after {
content: '\00007C';
color: theme-color('primary');
}
&:last-child:after a {
content: none;
}
}
}
}
Try something like this:
.l-footer-top {
.nav-item {
a {
color: $green;
padding: 0rem 0.5rem;
text-transform: uppercase;
&::after {
content: '\00007C';
color: theme-color('primary');
}
}
&:last-child a::after{
content:none
}
}
}
Your last-child is a <li> not an <a>

DRY Sass codes that only value changes

Using sass with rails. In the design, there is a pattern that the space shrink to half from desktop to mobile. Now it ends up like:
.my-page {
.class-a {
margin-top: 20px;
margin-bottom: 20px;
}
.class-b {
padding-top: 30px;
padding-bottom: 30px;
}
}
#media(min-width: 768px) {
.my-page {
.class-a {
margin-top: 40px;
margin-bottom: 40px;
}
.class-b {
padding-top: 60px;
padding-bottom: 60px;
}
}
}
Wondering is there a good way to DRY these? Don't wanna repeat writing same classes twice.
A nice way to DRY up your sass is using mixins.
#mixin page-spaces($margin, $padding) {
.my-page {
.class-a {
margin-top: $margin;
margin-bottom: $margin;
}
.class-b {
padding-top: $padding;
padding-bottom: $padding;
}
}
}
#include page-spaces(20px, 30px);
#media(min-width: 768px) {
#include page-spaces(40px, 60px);
}
SASS Reference on Mixins
Edit: In order to clarify the intended use of mixins, here's an extended version with multiple arguments (even a default):
#mixin awesome-page-stuff($stylish-margin, $cute-padding, $some-left-margin, $ugly-background: red) {
.my-page {
background: $ugly-background;
.class-a {
margin-top: $stylish-margin;
margin-bottom: $stylish-margin;
}
.class-b {
padding-top: $cute-padding;
padding-bottom: $cute-padding;
margin-left: $some-left-margin;
}
}
}
#include awesome-page-stuff(20px, 30px, 50px);
#media(min-width: 768px) {
#include awesome-page-stuff(40px, 60px, 200px, green);
}
you can create variables, something like this:
$primary-margin: 20px;
$primary-padding: 30px;
.my-page {
.class-a {
margin-top: $primary-margin;
margin-bottom: $primary-margin;
}
.class-b {
padding-top: $primary-padding;
padding-bottom: $primary-padding;
}
}
#media(min-width: 768px) {
.my-page {
.class-a {
margin-top: $primary-margin*2;
margin-bottom: $primary-margin*2;
}
.class-b {
padding-top: $primary-padding*2;
padding-bottom: $primary-padding*2;
}
}
}

Appending to class name via nesting with attribute selector

I have the following sass:
.list {
&__button{
cursor:pointer;
display: block;
padding: 4px;
border:1px solid $color4;
outline: none;
&__square {
border: 1px solid $color1;
width:12px;
height:12px;
}
&__text {
padding-right: 5px;
color: red;
}
}
&__button[state-selected="true"] {
.list__button__text {
color : $color1;
}
}
}
I have to use the full name of the class to get this part to work:
&__button[state-selected="true"] {
.list__button__text {
color : $color1;
}
}
Is there any way to simplify this part? Something like:
&__button[state-selected="true"] {
&__text {
color : $color1;
}
}
But this gives an error: Invalid parent selector for "&__text": ".list__button[state-selected="true"]".

Using SASS to extend selectors with elements

I'm working on an SCSS stylesheet, and I have a rule that looks something like this:
.footer-link-row {
color: red;
ul& {
padding: 0;
}
}
I want the ul& line compile to the selector ul.footer-link-row. However, this selector returns a compiler error, and using a &ul compiles to .footer-link-row ul. What's the correct way to select something like this?
--Added--
To clarify, the eventual CSS I want out of this is:
.footer-link-row {
color: red;
}
ul.footer-link-row {
padding: 0;
}
You want something like the following:
ul {
padding: 0;
.footer-link-row {
color: red;
}
}
The ampersand is used to require that both selectors match
a { text-decoration: none;
&:hover { border-width: 1px }
}
// compiles to
a {
text-decoration: none;
}
a:hover {
border-width: 1px;
}
If you want the ul.footer-link-row try
ul {
&.footer-link-row {
padding: 0;
}
.footer-link-row {
color: red;
}
}
Your clarification indicates that you need two scopes.
ul {
&.footer-link-row {
padding: 0;
}
}
.footer-link-row {
color: red;
}

Resources