Nested properties with common affix - css

In SCSS, properties with common prefix can be described as nested properties. Thus, as in the example,
.funky{
font: 2px/3px{
family: fantasy;
size: 30em;
weight: bold;
}
}
is compiled to:
.funky{
font: 2px/3px;
font-family: fantasy;
font-size: 30em;
font-weight: bold;
}
How do I do a similar thing with properties with common affix? How can I write a nested property that would be compiled to this:
.funky{
color: red;
background-color: green;
border-color: blue;
}

Sass has no construct for such a concept. You'll have to patch it or write a verbose mixin to do it.
#mixin color($background: null, $border: null, $font: null) {
background-color: $background;
border-color: $border;
color: $font;
}
.foo {
#include color($background: green, $font: red);
}

Related

Extend nested SASS selector inside another SASS file

I am looking for a way to reduce the repetition in my SASS. I have the following declaration, which is nested inside a selector.
Inside register.scss:
.btn-primary {
background-color: $brand-btn-primary;
color: #FFFFFF;
font-size: 16px;
line-height: 24px;
}
I would like to #extend that inside the selector in another SASS file but i'm unsure if that's possible.
admin.scss:
.btn-primary.upgrade-btn {
font-family: Helvetica;
background-color: $brand-btn-primary;
color: #FFFFFF;
font-size: 16px;
line-height: 24px;
border: 1px solid $brand-btn-primary;
min-width: 160px;
}
When I have attempted this I get the following error:
Error: complex selectors may not be extended.
Is there a way to do this?
You will need to remove the double class selector and extend using the method below.
.btn-primary {
background-color: $brand-btn-primary;
color: #ffffff;
font-size: 16px;
line-height: 24px;
}
.upgrade-btn {
#extend .btn-primary;
font-family: Helvetica;
border: 1px solid $brand-btn-primary;
min-width: 160px;
}

How to import a scss file inside a scss class

I want to add a different theme when i add "dark-theme" class to body. My implementation looks like this:
#import '../../../../node_modules/angular-grids/styles/material.scss';
.app-dark {
#import '../../../../node_modules/angular-grids/styles/material-dark.scss';
}
Without any luck. Any clue on how to do this?
There are two methods in order to do that. Both of them include mixins.
meta.load-css
The sass:meta feature gives the ability to do what you want.
Say you have this scss file with a theme:
//theme/_code.scss
$border-contrast: false !default;
code {
background-color: #6b717f;
color: #d2e1dd;
#if $border-contrast {
border-color: #dadbdf;
}
}
you can include that code inside another scss file like so:
// other-theme.scss
#use "sass:meta";
body.dark {
#include meta.load-css("theme/code",
$with: ("border-contrast": true));
}
This will result in the following css:
body.dark code {
background-color: #6b717f;
color: #d2e1dd;
border-color: #dadbdf;
}
You can read more about this feature here
old fashioned mixin
But you can do basically the same thing if you use mixin and include.
So, let's say you have this class you want to import into another class:
.title {
font-size: 2em;
font-weight: bold;
}
And another sass file with another theme:
.dark-theme {
.title {
font-size: 2em;
font-weight: bold;
color: white;
}
}
You can use a scss mixin and import it into both files:
mixin.scss
#mixin shared-items() {
.title {
font-size: 2em;
font-weight: bold;
}
}
then, in the theme files:
white-theme.scss
#import './mixin.scss';
/* will be included as is without a parent class */
#include shared-items;
dark-theme.scss
#import './mixin.scss';
/* will be included inside the dark-theme class */
.dark-theme {
.title {
color: white;
}
#include shared-items;
}
this will generate this css:
.title {
font-size: 2em;
font-weight: bold;
}
.dark-theme {
.title { color: white; }
.title {
font-size: 2em;
font-weight: bold;
}
}
Notice that you can also pass parameters to mixin and use them as functions.
So you can easily pass colors and use them with your theme variables.
for example:
# an example of giving a color to a placeholder mixin:
#mixin nk-placeholder($color: #C4C4CC) {
&::-webkit-input-placeholder {
color: $color;
font: inherit;
}
&::-moz-placeholder {
color: $color;
font: inherit;
}
&:-ms-input-placeholder {
color: $color;
font: inherit;
}
&:-moz-placeholder {
color: $color;
font: inherit;
}
&::placeholder {
color: $color;
font: inherit;
}
}
# same thing as above
#mixin shared-items($text-color: black) {
.title {
font-size: 2em;
font-weight: bold;
color: $text-color;
}
}
.white-theme {
#include shared-items;
}
.dark-theme {
#include shared-items(white);
}

Passing an extend as a mixin argument in SASS [duplicate]

My idea is that I would like to write silent classes for input[type=text], input[type="password"] and input[type=submit]. I would then #extend them in a mixin by passing hem through as a variable.
My parser is throwing this error;
Syntax error: Invalid CSS after " #extend ": expected selector_sequence, was "$type;"
Here is my code;
%text {
(text styling)
}
%password {
#extend %text;
}
%submit {
padding: .5em;
background-color: $button-color;
border: none;
cursor: pointer;
color: white;
border: 1px solid darken($button-color, 20%);
&:hover {
#include transition;
background-color: darken($button-color, 10%);
}
}
#mixin input($type) {
margin-bottom: 1.5em;
margin-left: 0;
outline: none;
#extend $type;
}
Any help would be appreciated
try using variables interpolation
#extend #{$type};
Further information on SASS Reference
While Fabrizio's answer is formally correct, consider not going that way.
There's a great rule in programming of any kind: "keep it simple, stupid!" aka KISS.
Though SASS provides such advanced facilities as extends and mixins, it doesn't mean that you should use them as much as possible. Don't make your code complicated when you don't have to!
This code does exactly what you want: applying styles to input[...] selectors:
input {
margin-bottom: 1.5em;
margin-left: 0;
outline: none;
}
input[type=text], input[type=password] {
font-family: Verdana; // Text styles
}
input[type=submit] {
padding: .5em;
background-color: $button-color;
border: none;
cursor: pointer;
color: white;
border: 1px solid darken($button-color, 20%);
&:hover {
#include transition;
background-color: darken($button-color, 10%);
}
}
If you want to apply styles to custom classes/ids, consider this approach:
/////////////////
// Silent classes
/////////////////
%input {
margin-bottom: 1.5em;
margin-left: 0;
outline: none;
}
%text {
#extend %input;
font-family: Verdana;
}
%password {
#extend %text;
}
%submit {
#extend %input;
padding: .5em;
background-color: $button-color;
border: none;
cursor: pointer;
color: white;
border: 1px solid darken($button-color, 20%);
&:hover {
#include transition;
background-color: darken($button-color, 10%);
}
}
///////////////////////////
// Applying silent classes:
///////////////////////////
.some .weirdly .nested input[type=text] {
#extend %text;
}
.password {
#extend %password;
}
#the-submit-button {
#extend %submit;
}
Demo: http://sassbin.com/gist/5956909/

How to refer css style from another?

Here's the sample:
.my-class {
font-size: 12px;
}
.my-another-class {
/* here I want to include .my-class style */
.my-class;
border: 0;
}
Can I include one css class into another or not?
You can define multiple targets for the .my-class rule, then specify further rules just for .my-another-class:
.my-class,
.my-another-class {
font-size: 12px;
}
.my-another-class {
border: 0;
}
You can even then override certain properties, for example
.my-class,
.my-another-class {
color: red;
font-size: 12px;
}
.my-another-class {
border: 0;
color: blue; /* overrides color: red; on .my-another-class */
}
You can't use a construction like this in plain CSS.
Preprocessors such as Less and Sass support this behaviour with mixins.
You can't, but you can do something like this:
.my-class, .my-another-class{
font-size: 12px;
}
.my-another-class {
border: 0;
}

scss join classes

So, this is the example of "LESS" code
.my_class{
color: #000;
font: 12px/12px Arial;
&_comething_else{ color: #f00; }
}
which will be compiled into this:
.my_class{
color: #000;
font: 12px/12px Arial;
}
.my_class_something_else{
color: #f00;
}
Classes ".my_class" and "_something_else" were joined,
but with SCSS this code will be compiled into this:
.my_class{
color: #000;
font: 12px/12px Arial;
}
.my_class _something_else{
color: #f00;
}
where is whitespace after ".my_class" before underscore in "_something_else"
So, is there any way to do this LESS trick in SCSS?
Thanks.
I found a solution. It's more uglier than in LESS but works:
$ns: ".my_class";
.my_class{
color: #000;
font: 12px/12px Arial;
#{$ns}_comething_else{ color: #f00; }
}
will be compiled into
.my_class{
color: #000;
font: 12px/12px Arial;
}
.my_class .my_class_comething_else{
color: #f00;
}
Even if it's still not possible to join class names in SASS(3.2.6) I noticed that you can do it over at jsFiddle.
Here is the code I've used:
.elem {
&__child {
border: solid red;
&-text {
color: blue;
}
}
}
Check out the examle http://jsfiddle.net/nicolasmn/6cvFZ/

Resources