How to combine multiple selectors within a class without prefixing every selector with & (parent operator) using SCSS? - sass

Let's say I have the following css:
.foo {
color: red;
}
.bar {
color: blue;
}
I want the final css to look like this:
.scope.foo {
color: red;
}
.scope.bar {
color: blue;
}
But I want to be able to just paste it somewhat unaltered, like some boilerplate that works like this:
.scope-class {
??? {
// put css here
}
}
Example:
.scope {
& {
.foo {
color: red;
}
.bar {
color: blue;
}
}
}
Obviously this doesn't work, but is there any way of archiving something like this, but keeping the css inside unaltered? I don't want to modify every selector like &.foo &.bar...

You could simply nest these classes in SCSS like this:
.scope {
&.foo {
color: red;
}
&.bar {
color: blue;
}
}

Related

How to use `^[N]` syntax in sass

I migrated from stylus to sass. In stylus, you can use ^[N] for partial quoting. How to do this in sass?
The Stylus feature Partial Reference has no direct equivalent in SCSS/SASS.
In SASS the & always contains the complete parent selector and there is no feature to retrieve only a part of it.
There are however...
the special #at-root to ditch the parent and...
a combined technique to capture the parent selector in a local-scoped variable and to use string interpolation to create a selector from it.
See what it does:
.foo {
.bar { color: red; }
#at-root .bar { display: block; }
}
renders to:
.foo .bar { color: red; }
.bar { display: block; }
and
.foo {
$block-class: &;
&__header {
font-size: medium;
#at-root #{$block-class}.large-header & { font-size: large; }
}
&__footer {
color: red;
}
}
renders to:
.foo__header {
font-size: medium;
}
.foo.large-header .foo__header {
font-size: large;
}
.foo__footer {
color: red;
}
A word of caution: I would not recommend to use such elaborate SCSS gymnastics to impress and confuse anyone who ever needs to read your code. Really, just keep it simple. Sometimes it is the right thing to do to just repeat a selector in the code. No harm done.

Prevent combination of multiple selectors

I'm trying to group all my vendor-specific stuff into a placeholder selector like this:
%search-bar-placeholder {
color: red;
}
.search-bar::-webkit-input-placeholder {
#extend %search-bar-placeholder;
}
.search-bar:-moz-placeholder {
#extend %search-bar-placeholder;
}
.search-bar::-moz-placeholder {
#extend %search-bar-placeholder;
}
.search-bar:-ms-input-placeholder {
#extend %search-bar-placeholder;
}
And then it compiles to this:
.search-bar::-webkit-input-placeholder, .search-bar:-moz-placeholder, .search-bar::-moz-placeholder, .search-bar:-ms-input-placeholder {
color: red; }
How can I make sure Sass doesn't put all the selectors together ? Like this:
.search-bar::-webkit-input-placeholder {
color: red;
}
.search-bar:-moz-placeholder {
color: red;
}
.search-bar::-moz-placeholder {
color: red;
}
.search-bar:-ms-input-placeholder {
color: red;
}
When looking at Extend/Inheritance at sass-lang.com it seems that the selectors will always be comma separated. Even if you add another property, it will keep the shared properties in the comma separated list, and add another selector just for that overridden value.
The way I achieved what you want is by using a mixin. Though it's not really the purpose of a mixin, it does get the job done. Your style is still centralized and you can print it out in each selector using a one liner too.
#mixin placeholder-properties() {
color: red;
font-weight: bold;
}
.search-bar::-webkit-input-placeholder {
#include placeholder-properties();
}
.search-bar:-moz-placeholder {
#include placeholder-properties();
}
.search-bar::-moz-placeholder {
#include placeholder-properties();
}
.search-bar:-ms-input-placeholder {
#include placeholder-properties();
}
The result will the following.
.search-bar::-webkit-input-placeholder {
color: red;
font-weight: bold;
}
.search-bar:-moz-placeholder {
color: red;
font-weight: bold;
}
.search-bar::-moz-placeholder {
color: red;
font-weight: bold;
}
.search-bar:-ms-input-placeholder {
color: red;
font-weight: bold;
}
Here's a fiddle.

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

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;
}
}

SASS using & for parent and that parent is first-child

I know you can specify if an element has a specific parent using &:
.btn {
.btn-group & {
color: blue;
}
}
But can you also say if the parent is btn-group and .btn-group is the first child?
Something like:
.btn {
.btn-group & &:first-child {
color: blue;
}
}
But that doesn't seem to work.
I worked out that I can do:
.btn {
.btn-group:first-child & {
color: blue;
}
}
But couldn't find a way to have multiple pseudo selectors (except using the above syntax with comma separated):
// This doesn't work :(
.btn {
.btn-group & {
&:first-child,
&:last-child {
color: blue;
}
}
}

Resources