Is there such a thing as an optional &? - css

Consider the following code:
#mixin bar() {
#if & {
&.bar {
display: none;
}
} #else {
.bar {
display: none;
}
}
}
#include bar();
.foo {
#include bar();
}
...which compiles to:
.bar {
display: none;
}
.foo.bar {
display: none;
}
Is there a way to write this mixin without duplicating the .bar block?

You can consider it as an argument with a default value that you can easily change:
#mixin bar($c:'.bar') {
#if & {
&#{$c} {
display: none;
}
} #else {
#{$c} {
display: none;
}
}
}

Related

How to add a tag in front of a sass rule?

I have this scss:
.nav {
&__item {
color: black;
}
}
This compiles to:
.nav__item
Is it possible to modify the above sccs so that it compiles with a tag in front of it, like the following?
a.nav__item
OR
li.nav_item
Here is one way using #at-root. This way avoids having to declare &__item twice.
.nav {
&__item {
color: black;
#at-root {
ul#{&} {
display: block;
}
}
}
}
Complies to
.nav__item {
color: black;
}
ul.nav__item {
display: block;
}
Try this:
.nav {
a#{&}__item {
color: black;
}
}
Output
.nav a.nav__item {
color: black;
}
Even though this is possible using
.nav {
a#{&}__item {
color: black;
}
}
I would highly encourage you to write it like this
a,
li {
&.nav {
&__item {
color: black;
}
}
}

SASS mixin that applies some rules when we call it

I would like to create a SASS/LESS mixin that asks if a variable is equal to some value then apply some CSS rules.
#mixin myTest($myVar: $num) {
#if ($myVar == $num) {
/* Apply rules if $myVar is set $num - I DO NOT KNOW WHAT SHOULD BE THERE */
} #else {
/* Do nothing */
}
}
And then I would like to use my mixin this way:
$num: 1;
#include myTest(1) {
h1 {
color: blue;
background: red;
}
}
#include myTest(2) {
h1 {
color: yellow;
background: green;
}
}
So that only the rules inside parentheses of #include myTest(1) { ... } are applied.
The problem is I dont know how to do that.
myTest checks the value of $myVar variable and applies passed css rules via #content - see documentation.
#mixin myTest($myVar: $num) {
#if ($myVar= $num) {
#content;
}
}
$num: 1;
#include myTest(1) {
h1 {
color: blue;
background: red;
}
}
#include myTest(2) {
h1 {
color: yellow;
background: green;
}
}
You neeed to use #content inyour mixin to get every thing that was in your mixin to be pushed through
$num: 1;
#mixin myTest($myVar: $num) {
#if ($myVar == $num) {
/* Apply rules if $myVar is set $num - I DO NOT KNOW WHAT SHOULD BE THERE */
#content; // this is how you get it in here
} #else {
/* Do nothing */
}
}
#include myTest(1) {
h1 {
background:red;
}
}
#include myTest(2) {
h1 {
background:blue;
}
}
https://codepen.io/anon/pen/YEJKRm
hopes this helps
I'm not quite sure I've understood your question fully, but it seems like what you need to do is move your CSS rules inside your mixin:
#mixin myTest($num) {
#if $num === 1 {
color: blue;
background: red;
} #else {
color: yellow;
background: green;
}
}
$num: 1;
h1 {
#include myTest($num);
}

SASS output grouping selectors

SCSS
.clearfix.scss {
background: #000;
}
.container1 {
#extend .clearfix;
}
.container2 {
#extend .clearfix;
}
.container3 {
#extend .clearfix;
}
CSS Output:
.clearfix, .container1, .container2, .container3, .container4, .container5 {
background: #000;
}
How can I remove this grouping selectors.
Compilied by gulp.
Using this task:
gulp.task('sass', function () {
return gulp.src('scss/style.scss')
.pipe(plumber())
.pipe(sass())
.pipe(autoprefixer(
{
browsers: ['last 15 versions'],
cascade: true
}
))
.pipe(csscomb())
.pipe(gulp.dest('css/'))
.pipe(connect.reload()) });
You are seeing the intended output of the #extend feature. It combines extended selectors in order to result in a smaller file output. You could try using a mixin instead.
SCSS:
#mixin clearfix {
background: #000;
}
.clearfix {
#include clearfix;
}
.container1 {
#include clearfix;
}
.container2 {
#include clearfix;
}
.container3 {
#include clearfix;
}
CSS output:
.clearfix {
background: #000;
}
.container1 {
background: #000;
}
.container2 {
background: #000;
}
.container3 {
background: #000;
}

Sass referencing parent selectors using the ampersand character within nested selectors

Just when I thought Sass was the coolest thing since sliced bread, it had to go and let me down. I'm trying to use the ampersand to select a parent of a nested item. It's a complex selection and its returning some unexpected results...
My sass:
.page--about-us {
a {
text-decoration:none;
}
.fa-stack {
.fa {
color:pink;
}
a & {
&:hover {
.fa-circle-thin {
color:red;
}
.fa-twitter {
color:blue;
}
}
}
}
}
Outputted CSS:
.page--about-us a {
text-decoration: none;
}
.page--about-us .fa-stack .fa {
color: pink;
}
a .page--about-us .fa-stack:hover .fa-circle-thin {
color: red;
}
a .page--about-us .fa-stack:hover .fa-twitter {
color: blue;
}
Expected Output (Note the placement of the a tag):
.page--about-us a {
text-decoration: none;
}
.page--about-us .fa-stack .fa {
color: pink;
}
.page--about-us a .fa-stack:hover .fa-circle-thin {
color: red;
}
.page--about-us a .fa-stack:hover .fa-twitter {
color: blue;
}
Demo:
http://sassmeister.com/gist/8ed68bbe811bc9526f15
You can store the parent selector in a variable!
Take the following BEM-like SASS:
.content-block {
&__heading {
font-size: 2em;
}
&__body {
font-size: 1em;
}
&--featured {
&__heading {
font-size: 4em;
font-weight: bold;
}
}
}
The selector inside of .content-block--featured is going to be .content-block--featured .content-block--featured__heading which might not be what you're after.
It's not as elegant as the single ampersand but you can stash the parent selector into a variable! So to get what you might be after from the above example without hard-coding the parent selector:
.content-block {
$p: &; // store parent selector for nested use
&__heading {
font-size: 2em;
}
&__body {
font-size: 1em;
}
&--featured {
#{$p}__heading {
font-size: 4em;
font-weight: bold;
}
}
}
So, OP, in your case you might try something like this:
.page--about-us {
$about: &; // store about us selector
a {
text-decoration:none;
}
.fa-stack {
.fa {
color:pink;
}
#{$about} a & {
&:hover {
.fa-circle-thin {
color:red;
}
.fa-twitter {
color:blue;
}
}
}
}
}
This is the normal behavior, as described in Sass documentation (link):
& will be replaced with the parent selector as it appears in the CSS. This means that if you have a deeply nested rule, the parent selector will be fully resolved before the & is replaced.
Meaning:
.foo {
.bar {
.baz & {
color: red;
}
}
}
Will render as:
.baz .foo .bar {
color: red;
}
And not:
.baz .bar {
color: red;
}
The right way to get your expected result is this one:
.page--about-us {
a {
text-decoration:none;
.fa-stack:hover {
.fa-circle-thin {
color:red;
}
.fa-twitter {
color:blue;
}
}
}
.fa-stack {
.fa {
color:pink;
}
}
}

Reference parent value

Is there any way I can reference parent value, like per example
.btn-blue {
background-color: $light-blue;
&:hover {
background-color: rgba($light-blue,.7);
}
}
.btn-green {
background-color: $light-green;
&:hover {
background-color: rgba($light-green,.7);
}
}
I would like to write one :hover selector which would get the value of the parent. Something like
.btn-blue {
background-color: $light-blue;
}
.btn-green {
background-color: $light-green;
}
.btn-green, .btn-blue {
&:hover {
background-color: rgba($parent_color,.7);
}
}
Any ideas?
You can use mxins and pass the color in:
#mixin btn-color($selColor)
{
background-color: $selColor;
&:hover { background-color: rgba($selColor,.7);
}
}
And use it like so:
.btn-green { #include btn-color($light-green); }
.btn-blue { #include btn-color($light-blue); }

Resources