This question already has an answer here:
cycling through a list of colors with sass
(1 answer)
Closed 7 years ago.
In the block of code below I have to write it 6 times to change the $blue to a different colour. There must be an easier and more DRY way to write this code.
&:nth-child(1) {
.fa-stack-1x { color: $white; }
.fa-circle { color: $blue; }
hr {
background: $blue;
background-image: linear-gradient(to right, $white, $blue, $white);
}
&:hover {
background: $blue;
.fa-stack-1x { color: $blue; }
.fa-circle { color: $white; }
a {
background-color: $white;
color: $blue;
}
hr {
background: $white;
background-image: linear-gradient(to right, $blue, $white, $blue);
}
}
}
So, turns out its quite easy, and the below solves the problem
$colours-list: $blue, $burgundy, $green, $orange, $purple, $red;
#each $current-colour in $colours-list {
$i: index($colours-list, $current-colour);
&:nth-child(#{$i}) {
.fa-stack-1x { color: $white; }
.fa-circle { color: $current-colour; }
hr {
background: $current-colour;
background-image: linear-gradient(to right, $white, $current-colour, $white);
}
a { background: $current-colour; color: $white; }
&:hover {
background: $current-colour;
.fa-stack-1x { color: $current-colour; }
.fa-circle { color: $white; }
a {
background-colour: $white;
color: $current-colour;
}
hr {
background: $white;
background-image: linear-gradient(to right, $current-colour, $white, $current-colour);
}
}
}
}
Related
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.
I am new to sass.
Here is my code in scss. Just wondering if this can be simplified further i.e i dont want to repeat the style color, text-decoration and transition.
a {
color: inherit;
text-decoration: none;
transition: all 0.3s;
}
div.menu-item-click {
&:hover, &:focus {
color: inherit;
text-decoration: none;
transition: all 0.3s;
}
}
Note exactly that use case is covvered better by ReSedano.
You cand do it using mixins:
#mixin mixinName {
color: inherit;
text-decoration: none;
transition: all 0.3s;
}
a {
#include mixinName;
}
div.menu-item-click {
&:hover, &:focus {
#include mixinName;
}
}
Also here is example with variables:
#mixin icon($width) {
width: $width;
stroke: currentColor;
}
.icon {
#include icon(25px);
}
And here is example with body
#mixin desktop ($xl: null) { // look here is default Value!
#media (min-width: if($xl, $xl, $screen-desktop)) {
#content; // here is true magic
}
}
.page {
#include desktop { // you may ignore variable because we have default
padding: 30px;
}
}
For this, maybe it is better using a placeholder with #extend directive (the output is less verbose than using a mixin):
%my-class {
color: inherit;
text-decoration: none;
transition: all 0.3s;
}
a {
#extend %my-class;
}
div.menu-item-click {
&:hover, &:focus {
#extend %my-class;
}
}
The output is:
a, div.menu-item-click:hover, div.menu-item-click:focus {
color: inherit;
text-decoration: none;
transition: all 0.3s;
}
We were provided a number of colors with specific hover-state colors associated:
$red: #cb333b;
$red-hover: #fe666e;
$brown: #544742;
$brown-hover: #877a75;
etc.
Since all the colors are formatted the same way, so I was hoping to write a mixin that takes the color's variable name, then concatenates -hover to the end. This is my first try:
#mixin button_colorizor($color) {
border-color: $color;
color: $color;
&:hover {
color: #{$color}-hover;
border-color: #{$color}-hover;
}
}
But what this does is output a color like this: #f1735f-hover. The same thing when I do this: color: #{$color+-hover};
You can create map of colors. And get color values by its names.
Demo on sassmeister.
$colors: (
red: #cb333b,
red-hover: #fe666e,
brown: #544742,
brown-hover: #877a75
);
#mixin button_colorizor($color) {
color: map-get($colors, $color);
border-color: map-get($colors, $color);
&:hover {
color: map-get($colors, $color + '-hover');
border-color: map-get($colors, $color + '-hover');
}
}
a {
#include button_colorizor(red);
}
span {
#include button_colorizor(brown);
}
This code is compiled to css:
a {
color: #cb333b;
border-color: #cb333b;
}
a:hover {
color: #fe666e;
border-color: #fe666e;
}
span {
color: #544742;
border-color: #544742;
}
span:hover {
color: #877a75;
border-color: #877a75;
}
I don't know if Sass is able to do this, but it doesn't hurt to ask.
The Problem
Basically I have three colors pattern that are repeated in multiple sections of application, like blue, green and orange. Sometimes what changes is the background-color, or the border-color of the component... Sometimes is the text color of a child element, etc.
What I thought?
1. Replace a string pattern inside a content.
.my-class {
#include colorize {
background-color: _COLOR_;
.button {
border-color: _COLOR_;
color: _COLOR_;
}
}
}
2. Providing a callback variable for #content.
// This is just a concept, IT DOESN'T WORK.
#mixin colorize {
$colors: blue, green, orange;
#each $colors in $color {
// ...
#content($color); // <-- The Magic?!
// ...
}
}
// Usage
#include colorize {
background-color: $color;
}
I tried to implement such solutions, but without success.
Instead of it...
See below my workaround to get it partially working:
#mixin colorize($properties) {
$colors: blue, green, orange;
#for $index from 1 through length($colors) {
&:nth-child(#{length($colors)}n+#{$index}) {
#each $property in $properties {
#{$property}: #{nth($colors, $index)};
}
}
}
}
You can use this mixin that way:
.some-class {
#include colorize(background-color);
}
What will come output:
.some-class:nth-child(3n+1) {
background-color: blue;
}
.some-class:nth-child(3n+2) {
background-color: green;
}
.some-class:nth-child(3n+3) {
background-color: orange;
}
The problem? Well, I can't use it with child selectors.
Based on the above information, there is some magic solution for this case?
I think I figured out what you meant; it is a little (very) messy, but it should do what you want:
#mixin colorize($parentProperties,$childMaps) {
$colors: blue, green, orange;
#for $index from 1 through length($colors) {
&:#{nth($colors, $index)} {
#each $property in $parentProperties {
#{$property}: #{nth($colors, $index)};
}
}
#each $mapped in $childMaps {
$elem: nth($mapped,1);
$properties: nth($mapped,2);
#{$elem}:nth-child(#{length($colors)}n+#{$index}) {
#each $property in $properties {
#{$property}: #{nth($colors, $index)};
}
}
}
}
}
It would turn out to be:
/* -------------- USAGE ------------------*/
.some-class {
#include colorize(
background-color,( //Parent properties
(button, background-color), //Child, (properties)
(span, (background-color,border-color)) //Child, (properties)
)
);
}
/* --------------- OUTPUT ----------------*/
.some-class:nth-child(3n+1) {
background-color: blue;
}
.some-class button:nth-child(3n+1) {
background-color: blue;
}
.some-class span:nth-child(3n+1) {
background-color: blue;
border-color: blue;
}
.some-class:nth-child(3n+2) {
background-color: green;
}
.some-class button:nth-child(3n+2) {
background-color: green;
}
.some-class span:nth-child(3n+2) {
background-color: green;
border-color: green;
}
.some-class:nth-child(3n+3) {
background-color: orange;
}
.some-class button:nth-child(3n+3) {
background-color: orange;
}
.some-class span:nth-child(3n+3) {
background-color: orange;
border-color: orange;
}
Hope that that is what you are looking for :)
I'm trying to make a mixin to produce results similar to the following:
#media (max-width: 767px)
{
.m-text-left
{
text-align: left;
}
.m-text-right
{
text-align: right;
}
.m-text-center
{
text-align: center;
}
.m-float-right
{
float: right;
}
.m-float-left
{
float: left;
}
.m-float-none
{
float: none;
}
.m-text-justify
{
text-align: justify;
}
.m-hide
{
visibility: hidden;
overflow: hidden;
max-height: 0;
}
.m-remove
{
display: none;
}
}
/* Portrait tablet to landscape */
#media (min-width: 768px) and (max-width: 1029px)
{
.t-text-left
{
text-align: left;
}
.t-text-right
{
text-align: right;
}
.t-text-center
{
text-align: center;
}
.t-float-right
{
float: right;
}
.t-float-left
{
float: left;
}
.t-float-none
{
float: none;
}
.t-text-justify
{
text-align: justify;
}
.t-hide
{
visibility: hidden;
overflow: hidden;
max-height: 0;
}
.t-remove
{
display: none;
}
}
/* Landscape to small desktop */
#media (min-width: 1030px)
{
.d-text-left
{
text-align: left;
}
.d-text-right
{
text-align: right;
}
.d-text-center
{
text-align: center;
}
.d-float-right
{
float: right;
}
.d-float-left
{
float: left;
}
.d-float-none
{
float: none;
}
.d-text-justify
{
text-align: justify;
}
.d-hide
{
visibility: hidden;
overflow: hidden;
max-height: 0;
}
.d-remove
{
display: none;
}
}
This is the mixin I wrote:
#mixin respond($responsive-classes) {
#each $screen, $query in (
m: max-width $small-screen, // Phones
p: min-width $small-screen+1 max-width $medium-screen, // Phones to Phablets
t: min-width $medium-screen+1 max-width $large-screen, // Phablets to Tablets
l: min-width $large-screen+1 max-width $wide-screen, // Tablets to Desktops
d: min-width $wide-screen+1) { // Desktops
#include media($query, $grid-columns) {
#each $selector, $properties in $responsive-classes {
#if (length($properties) == 1 AND length(nth($properties, 2)) > 1) {
#each $value in nth($properties, 2) {
.#{$screen}-#{$selector}-#{$value} {
#{nth($properties, 1)}: #{$value};
}
}
} #else {
#each $property, $value in $properties {
.#{$screen}-#{$selector} {
#{$property}: #{$value};
}
}
}
}
}
}
}
This is how I used it:
#include respond((
(text, (text-align, (left, right, center, justify))),
(float, (float, (left, right, none))),
(hide, (visibility, hidden), (overflow, hidden), (max-height, 0)),
(remove, (display, none))
));
This is the result I'm getting:
#media screen and (max-width: 480px) {
.m-float,
.m-text {
left: right
}
}
#media screen and (min-width: 481px) and (max-width: 620px) {
.p-float,
.p-text {
left: right
}
}
#media screen and (min-width: 621px) and (max-width: 955px) {
.t-float,
.t-text {
left: right
}
}
#media screen and (min-width: 956px) and (max-width: 1200px) {
.l-float,
.l-text {
left: right
}
}
#media screen and (min-width: 1201px) {
.d-float,
.d-text {
left: right
}
}
.hide {
visibility: hidden;
overflow: hidden;
max-height: 0
}
Ignore the media queries; I know they're different. It's the overall final result that I want.
I was putting in lists instead of maps.
The Mixin:
#mixin respond($modifier-class) {
#each $screen, $query in (
m: max-width $small-screen, // Phones
p: min-width $small-screen + 1 max-width $medium-screen -1, // Phones to Phablets
t: min-width $medium-screen max-width $large-screen, // Phablets to Tablets
l: min-width $large-screen + 1 max-width $wide-screen - 1, // Tablets to Desktops
d: min-width $wide-screen) { // Desktops
#include media($query) { // Mixin from Bourbon's Neat
#each $selector, $rules in $modifier-class {
#each $property, $values in $rules {
#if (type-of($values) == "list") {
#each $value in $values {
.#{$screen}-#{$selector}-#{$value} {
#{$property}: $value;
}
}
} #else {
.#{$screen}-#{$selector} {
#{$property}: $values;
}
}
}
}
}
}
}
The call:
$modifier-classes: (
text: ( text-align: (left, right, center, justify) ),
float: ( float: (left, right, none) ),
hide: ( visibility: hidden,
overflow: hidden,
max-height: 0, ),
remove: ( display: none )
);
#include respond($modifier-classes);