My SASS code:
// rem calculator
#function calculateRem($size) {
$remSize: $size / 16px;
#return #{$remSize}rem;
}
#mixin fontsize($size) {
font-size: $size; //Fallback in px
font-size: calculateRem($size);
}
// variables
$font-size-regular: fontsize(16px);
// css
body {
font-size: $font-size-regular;
}
This outputs: font-size: fontsize(16px);
Using #include fontsize(16px); does work. but I want to put it in a variable if possible
You may do this
// rem calculator
#function calculateRem($size) {
$remSize: $size / 16px;
#return #{$remSize}rem;
}
#mixin fontsize($size) {
font-size: $size; //Fallback in px
font-size: calculateRem($size);
}
// variables
$font-size-regular: 16px;
// css
body {
#include fontsize($font-size-regular);
}
Related
So let's say I have the following mixins:
#mixin type-h1 {
font-size: 36px;
font-weight: bold;
}
#mixin type-h2 {
font-size: 28px;
font-weight: bold;
}
#mixin type-h3 {
font-size: 24px;
font-weight: bold;
}
Now I created utility classes:
.type-h1 {
#include type-h1;
}
.type-h2 {
#include type-h2;
}
.type-h3 {
#include type-h3;
}
All good so far. Now I would like to simplify my code and generate the utility classes using Sass loops. This is what I have:
$variable: 1, 2, 3;
#each $value in $variable {
.type-h#{$value} {
#include type-h$variable;
}
}
Anyone has an idea why this loop doesn't work?
You can create map with variables:
$vars: (1: 36px, 2: 28px, 3: 24px);
Then combine mixins into one:
#mixin types($value) {
font-size: $value;
font-weight: bold;
}
And finally you can generate your utilities by:
#each $size, $value in $vars {
.type-h#{$size} {
#include types($value);
}
}
Here is link to Codepen.io with example
I need a SCSS mixin to make borders with. In this mixin, the $position variable, should be optional:
#mixin border($position, $width, $style, $color) {
#if $position {
border-#{$position}: $width $style $color;
} #else {
border: $width $style $color;
}
}
This is necessary so that I can use it in these 2 types of cases:
.box {
#include border('bottom', 1px, solid, #999) /*with position*/;
}
and
.button {
#include border(1px, solid, #999); /*without position*/
#include border-radius(9999999px);
padding: .5rem .75rem;
font-size: 14px;
}
For the second case, the compiler throws the error:
Mixin border is missing argument $color.
What am I doing wrong?
You can use default parameter for $position. I used the false boolean for default variable.
#mixin border($width, $style, $color, $position: false) {
#if $position {
border-#{$position}: $width $style $color;
} #else {
border: $width $style $color;
}
}
And you can use like this:
.button {
#include border(1px, solid, #999);
padding: 0.5rem 0.75rem;
font-size: 14px;
}
If you don't send any parameter, it enters else state (like above). If you send a position parameter, it enters the if state. Like this:
.button {
#include border(1px, solid, #999, right);
padding: 0.5rem 0.75rem;
font-size: 14px;
}
Also, keep in mind that optional parameters must come after mandatory parameters. This is a rule.
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);
}
I checked the following article in which it presented the following mixing:
rem font size with pixel fallback
#function calculateRem($size) {
$remSize: $size / 16px;
#return $remSize * 1rem;
}
#mixin font-size($size) {
font-size: $size;
font-size: calculateRem($size);
}
I feel very confortable using rem on my projects, after placing font-size: 62.5% on the html so 1rem = 10pixels.
But I would like to know if there is a mixing or a method to create a pixel fallback for any rem used in a whole project, as for example:
&:before{
color: white;
margin: 0 0.5rem 0 0;
left: 0;
text-align: center;
top: 0;
width: 3.2rem;
}
In this case the margin-right = 5pixels and width 32pixels. The issue with rem units is that IE8, Opera mini or Safari 3.2 is not supported. So the site would not be correctly visible from any of these browsers.
Is there a way to automate the pixel fallback using rem throughout a project?
Here is a solution so you can use the rem to px mixin for any property:
html {
font-size: 62.5%;
}
#function calculateRem($size) {
$remSize: $size / 10px;
#return #{$remSize}rem;
}
#mixin rem($propertie, $value) {
#{$propertie}: $value;
#{$propertie}: calculateRem($value);
}
p {
font-size: calculateRem(32px);
#include rem(width, 100px);
#include rem(margin, 50px);
}
OUTPUT
html {
font-size: 62.5%;
}
p {
font-size: 3.2rem;
width: 100px; /* Fallback */
width: 10rem;
margin: 50px; /* FallBack */
margin: 5rem;
}
An example: http://sassmeister.com/gist/e888e641925002b5895c
This solution will work with shortcut properties that contain mixed values.
// Global Var
$root-font-size: 16;
#mixin rem($property, $values) {
$pxvalues: null;
$remvalues: null;
#each $value in $values{
$pxvalue: null;
$remvalue: null;
#if type-of($value) == 'number'{
#if ($value > 0 or $value < 0){
$pxvalue: ($value)+px;
$remvalue: ($value / $root-font-size)+rem;
} #else {
$pxvalue: $value;
$remvalue: $value;
}
} #else {
$pxvalue: $value;
$remvalue: $value;
}
$pxvalues: append($pxvalues, $pxvalue);
$remvalues: append($remvalues, $remvalue);
}
#{$property}: $pxvalues;
#{$property}: $remvalues;
}
// Usage: pass pixel values without units
.foo{
#include rem(margin, 80 auto);
}
Output:
.foo{
margin: 80px auto;
margin: 5rem auto;
}
I am working on a stylesheet for a multisite.
I have to declare a font-size in one variable, and the variable would change depending on the selectors. Eg:
$newfont : 10px;
i am attempting this which of course is not working:
#if ( #header ) {
$newfont: 30px;
}# else if ( #footer ) {
$newfont: 25px;
}
Can someone please point out what i am doing wrong?
I am sorry but why don't you use
#header{
font-size: 30px;
}
#footer{
font-size:25px;
}
and as pointed out in the comment below you can use a mixin.
I'm not sure what you are trying to achieve, but #if requires a SassScript expression. What you are passing is actually a selector. If you want to apply different font size for different containers I'll suggest to use a function or mixin. For example:
#function get-font-size($type) {
#if $type == "header" {
#return 30px;
} #else if $type == "footer" {
#return 25px;
}
}
#header {
font-size: get-font-size("header");
}
#footer {
font-size: get-font-size("footer");
}
The code produces:
#header {
font-size: 30px;
}
#footer {
font-size: 25px;
}
You may even control the process with a variable as you tried actually:
$newfontsize: 30px;
#mixin update-font-size($size) {
$newfontsize: $size;
}
#function get-font-size() {
#return $newfontsize;
}
#header {
font-size: get-font-size();
}
#include update-font-size(15px);
#footer {
font-size: get-font-size();
}
The simplest solution is to just use more variables. This is how most theming libraries do it.
$header-font-size: 30px !default;
$footer-font-size: 25px !default;
#header{
font-size: $header-font-size;
}
#footer{
font-size: $footer-font-size;
}