SASS function for #extend - css

What I'm trying to achieve, is simply a shorter version of the #extend function in sass.
I have a heap of classes which I use all over my site for layout.
Example:
.grid1 {width:40px;}
.grid2 {width:80px;}
.grid3 {width:120px;}
.grid4 {width:160px;}
.grid5 {width:200px;}
I know you can use the extend function to remove duplicate css all over the site with:
.class {#extend .grid1}
which would output
.class {width:40px}
What I'm after is something a little more simple.
.class{grid(1)};
Here's what I've tried:
#function grid($n){
#extend unquote(".grid#{$n}");
}
Obviously this doesn't work, any ideas?

#functions in SASS are meant to be used to manipulate values. So the reason why this will not work is due to the fact that you are trying to return selectors and declaration blocks. This is what mixins are for.
One way of doing this would be:
$grids: ((5, 40), (10, 80), (15, 120), (20, 160));
#mixin grid($n, $fluid: false) {
#if($fluid) {
width: nth(nth($grids, $n), 1) + "%";
} #else {
width: nth(nth($grids, $n), 2) + "px";
}
}
.foo {
#include grid(3);
}
.bar {
#include grid(4, true);
}
Which produces:
.foo {
width: "120px"; }
.bar {
width: "20%"; }

Related

SASS: Is there a way to cusomize the sass syntax?

I have an scss function like this
#function dpx($size) {
#return calc(var(--dpx, 10px) * #{$size});
}
This is working fine like this:
h1 {
font-size: dpx(1.6);
}
But I think it's a little verbose since I need to use it everywhere and I want to make this function more feels like a unit.
I know sass is a precompiler, can I somehow to make the following syntax compiles into dpx(1.6)?
h1 {
font-size: 1.6dpx;
}
You could centralize font-sizing using CSSVariables (no SCSS required)
* {
font-size: calc(var(--dpx, 10px) * var(--fs));
}
.a { --fs: 1; }
.b { --fs: 2; }
.c { --fs: 3; }
.d { --fs: 4; }
<h2 class="a">lorem</h2>
<h2 class="b">lorem</h2>
<h2 class="c">lorem</h2>
<h2 class="d">lorem</h2>

The Sass ampersand and attribute selectors

I want to create a sass file that the selectors will be attribute selectors.
When I work with class selectors, in most of the cases I will do
.parent {
&-child {
}
}
which gives me the following css: .parent-child {}.
I want to achieve the same thing with attribute selectors:
[data-parent] {
&-child {
}
}
which I want to become: [data-parent-child] {}
someone knows how to achieve this? thanks.
You can use this mixin as a workaround to get the desired result.
#mixin child-attribute($child) {
$string: inspect(&);
$original: str-slice($string, 3, -4);
#at-root #{ selector-replace(&, &, "[#{$original}#{$child}]" ) } {
#content;
}
}
The code simply does the following
$string variable is responsible for turning the parent selector to a string using the inspect function
$original variable is responsible for getting the text content of the $string variable i.e the value 'data-parent' from '([data-parent])'
selector-replace function then replaces the parent selector with the concatenation of the $original variable and child variable
When used in the following ways
[data-parent] {
#include child-attribute('-child') {
color: green;
}
}
The css output
[data-parent-child] {
color: green;
}
Depending on what you want to achieve, it can also be used like this
[grandparent] {
#include child-attribute('-parent') {
color: white;
#include child-attribute('-child') {
color: blue;
}
}
}
Which generates the following css
[grandparent-parent] {
color: white;
}
[grandparent-parent-child] {
color: blue;
}
Hope this helps you
You can create mixin that will set styles for elements with data attribytes.
Scss:
#mixin data($name) {
[data-#{$name}] {
#content;
}
}
* {
#include data('lol') {
color: red;
};
}
Css output:
* [data-lol] {
color: red;
}
DEMO
I would go down a slightly different route of having a class on your elements that contain the data attributes.
<div class="data-obj" data-parent="true"></div>
<div class="data-obj" data-parent-child="true"></div>
then in your SASS do
.data-obj {
...
&[data-parent] { ... }
&[data-parent-child] { ... }
}

Vaadin, change grid column color

I want to change the column color of my grid. Unfortunately nothing happens... here is my code:
grid.setCellStyleGenerator(( Grid.CellReference cellReference ) -> {
if ( "name".equals( cellReference.getPropertyId() ) ) {
return "highlight-green";
} else {
return "rightAligned";
}
});
mytheme.scss:
#import "../valo/valo.scss";
#mixin mytheme {
#include valo;
// Insert your own theme rules here
.rightAligned {
text-align: right;
}
.v-table-row.v-table-row-highlight-green,
.v-table-row-odd.v-table-row-highlight-green {
background-color: #00ff00;
}
}
The rightAligned works great, but highlight-green doesn't
Try to add background-color: #00ff00 !important;
It looks like you need to rewrite existing styles of your framework, !important must help with this.

Is it possible to set empty string as a class selector in sass?

I have a variable which have empty string as default value and it can be changed dynamically based on skin name. So I tried to write my sass selector like this.
default.scss:
$skin: '';
green.scss:
$skin: 'green';
main.scss:
#import 'default.scss';
.#{$skin} .header{
color: black;
}
So I expected the below output from generated CSS.
.header{
color: black;
}
and
.green .header{
color: black;
}
But it throws below error while compiling
Invalid CSS after ".": expected class name, was ".header"
You could use a function for this:
$skin: 'green';
#function skin(){
#if $skin != '' { #return '.' + $skin + ' '; }
#else { #return ''; }
}
Now you could use it like this:
#{skin()} .header { ... }
Which will output:
.green .header { display: block; }
It might be better to use a better global variable name (skin seems like something that might quickly be reused - I would suggest something like $global-skin-name or something, but thats just semantics).

How can I create a Sass mixin with a class as a variable

I am trying to write something like this :
#mixin variableChild($child:".theChild") {
//some css
$child {
//css specific to the child
}
}
#parent { #include variableChild(".specificChild"); };
So it would generate this CSS :
#parent {//some css}
#parent .specificChild {
//css specific to the child
}
You were almost right, you just missed the #{} around your child selector I think. There’s more information about it in the Sass documentation.
#mixin variableChild($child:".theChild") {
#{$child} {
color: red;
}
}
#parent {
#include variableChild(".specificChild");
};
http://jsfiddle.net/UrLdB/

Resources