SASS Mixin: only apply hover style if class is on a link? - sass

I'm attempting to set a bunch of background colours using a mixin. I'd also like to apply hover styling to these background colours IF the classes are assigned to a link element:
#mixin bg-color($color) {
background-color: $color;
&[ifthisisalink] {
&:hover {
background-color: darken($color, 10%);
}
}
}
.bg-blue {
#include bg-color(blue);
}
So if we have .bg-blue on a plain div, there is no hover color. But if .bg-blue is on a link, there is a hover color:
<div class="bg-blue">Hover on me and nothing happens.</div>
Hover on me and I go darker.
Is this possible in SASS?

You need #at-root:
#mixin bg-color($color) {
background-color: $color;
#at-root {
a#{&} {
&:hover {
background-color: darken($color, 10%);
}
}
}
}
.bg-blue {
#include bg-color(blue);
}

Related

If mixins in empty show default

Is it possible to have a mixin that can override a current code block? I want to have it so that if the #mixin is empty the background for the box would be empty and then show in orange, but when I remove the #mixin it does not change to orange? What am I doing wrong?
#mixin box {
background: red;
}
.box {
#if box {
#include box;
} #else {
background: orange;
}
}
The $color: null is just for setting a value if you didn't pass a value for your #mixin. after that you can check easily inside your #mixin using #if #else.
Sass
#mixin background-color($color: null) {
#if($color) {
background-color: $color;
} #else {
background-color: orange;
}
};
h1 {
#include background-color(red);
}
h2 {
#include background-color(green);
}
h3 {
#include background-color();
}
h4{
#include background-color(blue)
}
Html
<h1>color</h1>
<h2>color 2</h2>

Sass Mixin: Callback or Replace #content

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 :)

Not last child mixin SASS

Is it possible to turn this:
.redstripe p:not(last-child) {
border-bottom:1px solid red;
}
Into a mixin so that I can apply it to any element and assign a child tag to it like:
#mixin redstripe (this.$children):not(last-child) {
border-bottom:1px solid red;
}
And then apply:
div {
#include redstripe(p);
}
What is the correct way to implement this?
Here's a general purpose mixin like you've described.
DEMO
#mixin not-last-child($selector) {
& #{$selector}:not(:last-child) {
#content;
}
}
We can pass it a selector string to use.
SCSS:
.thing {
#include not-last-child('p') {
color: red;
}
}
CSS:
.thing p:not(:last-child) {
color: red;
}
Sass Documentation

Finding if a string is in string in sass

I want an if statement to show if a string is inside another string in sass.
How do i do this in a mixin?
#mixin hello($mystring) {
}
You can use str-index to achieve this.
SCSS
#mixin hello($mystring) {
#if (str-index("Hello World", $mystring)) {
background-color: green;
}
#else {
background-color: blue;
}
}
.test {
#include hello("World");
}
CSS Output
.test {
background-color: green;
}

Set both normal and hover style with SASS

This seems like a basic question but I cant find the answer anywhere. How can I set both the normal and :hover styles for a link with SASS?
I want to control the default and hover styles for all links in one place and be able to pass this 'variable' (or whatever the correct word is) to different selectors throughout my CSS.
So similar to the code below but I want to control the default and hover style on the first line. So later if I wanted these links to have an :active style I could just add it once at the top of the page.
$primary-color: #333;
.some-class {
color: $primary-color;
}
.some-class-other-class {
color: $primary-color;
}
Solution for any selector:
&,
&:hover {
color: red;
}
E.g.
.my-class {
&,
&:hover {
color: red;
}
}
If you specifically only want to target all links:
a, a:hover {
color: red;
}
This works:
#mixin style-1 {
background: red;
&:hover {
background: $blue
}
}
.something {
#include style-1;
}
.something-else {
#include style-1;
}
.something-else-again {
#include style-1;
}
You can try:
a{
&:link, &:hover{
color: $primary-color;
}
&:active{
color: $other-color;
}
}

Resources