For the implementation of RTL and LTR styles using scss I created two scss files _ltr.scss and _rtl.scss and based on the country selection of user in the application, I dynamically import the corresponding stylesheet.
_ltr.scss
$start-direction: left;
#mixin paddingStart($val) {
padding-#{$start-direction}: $val;
}
_rtl.scss
$start-direction: right;
#mixin paddingStart($val) {
padding-#{$start-direction}: $val;
}
main.js //where country switch happening
const root = document.documentElement;
root.classList.remove('rtl');
root.classList.add('ltr');
if (USER COUNTRY DIR VALUE === 'RTL') {
root.classList.remove('ltr');
root.classList.add('rtl');
}
_main.scss
html.ltr {
#import '_ltr.scss';
}
html.rtl {
#import '_rtl.scss';
}
#if mixin-exists(paddingStart) { //NOT WORKING
#include paddingStart(10px)
}
This is how I dynamically import the scss, and it works correctly. But the mixin exists if statement is always failing. Is there any ways to make the mixin work as expected in SCSS? Or any options to implement this LTR and RTL style better way. Because in my case user can change the country and based on his selection I have to load the styles dynamically.
SCSS is compiled before arriving to the browser and deployed, Javascript is run after it arrived to the browser. You are trying to modify SCSS with Javascript something that doesn't really exist.
What you need is to have both rtl.scss ltr.scss loaded at the same time, and apply the rules depending on the direction.
For rtl the easier way is to create a mixin where you can set/modify rules if the site is in rtl.
#mixin rtl {
body:dir(rtl) &{
#content;
}
}
You shouldn't type .scss when importing files. https://sass-lang.com/documentation/at-rules/import#importing-css
html.ltr {
#import 'ltr';
}
html.rtl {
#import 'rtl';
}
I am trying to use media queries in Bootstrap 4.
On their website they do this:
#include media-breakpoint-up(xs) { ... }
#include media-breakpoint-up(sm) { ... }
#include media-breakpoint-up(md) { ... }
#include media-breakpoint-up(lg) { ... }
#include media-breakpoint-up(xl) { ... }
// Example usage:
#include media-breakpoint-up(sm) {
.some-class {
display: block;
}
}
So I grabbed the Bootstrap SCSS, and copied the _breakpoints.scss and included this in my project. I import it, and then try to use a media query:
#import "partials/breakpoints";
#include media-breakpoint-up(sm) {
.mycontainer {
background-color: black;
}
}
However, I get the following error when i compile SASS:
Change detected to: main.scss
error pages/_geschichte.scss (Line 54: Undefined variable: "$grid-breakpoints".)
Am I doing this the wrong way or will I need to include more files? I then tried to fix that by also including _grid.scss, but then for this, something else is required again, so I got unsure whether this is indeed the right way and thought I'd better ask.
Did you include the bootstrap variables.scss ?
Seems like the variables are missing
It seems like this can be done... but all the suggestions I've seen online aren't working for me. I have a customFont.ttf tile that I'm putting in this dir: 'home/greg/Documents/MapBox/project/myproject/customFont.ttf'
Then I'm using this code:
Map { font-directory: url(customFont.ttf); }
or
Map { font-directory: url(''); }
or
Map { font-directory: url(fonts/customFont.ttf); }
but nothing is working. I just get en error message such as:
"Invalid value for text-face-name, the type font is expected. comicSansMs, Arial Regular (of type string) was given. (line 71)"
any tips?
place your fonts in the folder app/assets/fonts, lib/assets/fonts or vendor/assets/fonts
If Rails 4+, you can only place your fonts in the folder app/assets/fonts.
In css:
#font-face {
font-family: 'customFont';
src:url('customFont.ttf');
font-weight: normal;
font-style: normal;
}
I am trying to put font family for a div if the variable is not equal to null.
my less code is
div.content {
& when (isstring(#contentFont)) {
font-family: #contentFont;
}
}
the output that I get from css is
div.content when (isstring(#contentFont)) {
font-family: Abel;
}
my problem is, the style is not applying for the div.content, not sure what i am doing wrong. Any help would be greatly appreciated.
As discussed in the comments, you're using version 0.4.0 of lessphp – which doesn't seem to support the shorthand guard (when) syntax that you're trying to use.
It looks like it does support guards on mixins, however.
Try splitting your code into a mixin and a usage of this mixin, like this:
/* the mixin */
.fontIfString(#font) when (isstring(#font)) {
font-family: #font;
}
/* usage */
#contentFont: "hello";
div.content {
.fontIfString(#contentFont);
}
I'm trying to use string interpolation on my variable to reference another variable:
// Set up variable and mixin
$foo-baz: 20px;
#mixin do-this($bar) {
width: $foo-#{$bar};
}
// Use mixin by passing 'baz' string as a param for use $foo-baz variable in the mixin
#include do-this('baz');
But when I do this, I get the following error:
Undefined variable: "$foo-".
Does Sass support PHP-style variable variables?
This is actually possible to do using SASS maps instead of variables. Here is a quick example:
Referencing dynamically:
$colors: (
blue: #007dc6,
blue-hover: #3da1e0
);
#mixin colorSet($colorName) {
color: map-get($colors, $colorName);
&:hover {
color: map-get($colors, #{$colorName}-hover);
}
}
a {
#include colorSet(blue);
}
Outputs as:
a { color:#007dc6 }
a:hover { color:#3da1e0 }
Creating dynamically:
#function addColorSet($colorName, $colorValue, $colorHoverValue: null) {
$colorHoverValue: if($colorHoverValue == null, darken( $colorValue, 10% ), $colorHoverValue);
$colors: map-merge($colors, (
$colorName: $colorValue,
#{$colorName}-hover: $colorHoverValue
));
#return $colors;
}
#each $color in blue, red {
#if not map-has-key($colors, $color) {
$colors: addColorSet($color, $color);
}
a {
&.#{$color} { #include colorSet($color); }
}
}
Outputs as:
a.blue { color: #007dc6; }
a.blue:hover { color: #3da1e0; }
a.red { color: red; }
a.red:hover { color: #cc0000; }
Sass does not allow variables to be created or accessed dynamically. However, you can use lists for similar behavior.
scss:
$list: 20px 30px 40px;
#mixin get-from-list($index) {
width: nth($list, $index);
}
$item-number: 2;
#smth {
#include get-from-list($item-number);
}
css generated:
#smth {
width: 30px;
}
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#lists
http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#list-functions
Anytime I need to use a conditional value, I lean on functions. Here's a simple example.
$foo: 2em;
$bar: 1.5em;
#function foo-or-bar($value) {
#if $value == "foo" {
#return $foo;
}
#else {
#return $bar;
}
}
#mixin do-this($thing) {
width: foo-or-bar($thing);
}
Here's another option if you're working with rails, and possibly under other circumstances.
If you add .erb to the end of the file extension, Rails will process erb on the file before sending it to the SASS interpreter. This gives you a can chance to do what you want in Ruby.
For example: (File: foo.css.scss.erb)
// Set up variable and mixin
$foo-baz: 20px; // variable
<%
def do_this(bar)
"width: $foo-#{bar};"
end
%>
#target {
<%= do_this('baz') %>
}
Results in the following scss:
// Set up variable and mixin
$foo-baz: 20px; // variable
#target {
width: $foo-baz;
}
Which, of coarse, results in the following css:
#target {
width: 20px;
}
I came across the need to reference a colour dynamically recently.
I have a _colours.scss file for every project, where I define all my colours once and reference them as variables throughout.
In my _forms.scss file I wanted to setup button styles for each colour available. Usually a tedious task. This helped me to avoid having to write the same code for each different colour.
The only downside is that you have to list each colour name and value prior to writing the actual css.
// $red, $blue - variables defined in _colours.scss
$colours:
'red' $red,
'blue' $blue;
#each $name, $colour in $colours {
.button.has-#{$name}-background-color:hover {
background-color: lighten($colour, 15%);
}
}
I needed to use dynamic color values in sass variables.
After lots of search, I applied this solution:
In application.html.erb:
<style>
:root {
--primary-color: <%= current_client.header_color %>;
--body-color: <%= current_client.footer_color %>;
}
</style>
In variables.sass:
$primary: var(--primary-color);
And boom you are good to go!
Reference: https://medium.com/angular-in-depth/build-truly-dynamic-theme-with-css-variables-539516e95837
To make a dynamic variable is not possible in SASS as of now, since you will be adding/connecting another var that needs to be parsed once when you run the sass command.
As soon as the command runs, it will throw an error for Invalid CSS, since all your declared variables will follow hoisting.
Once run, you can't declare variables again on the fly
To know that I have understood this, kindly state if the following is correct:
you want to declare variables where the next part (word) is dynamic
something like
$list: 100 200 300;
#each $n in $list {
$font-$n: normal $n 12px/1 Arial;
}
// should result in something like
$font-100: normal 100 12px/1 Arial;
$font-200: normal 200 12px/1 Arial;
$font-300: normal 300 12px/1 Arial;
// So that we can use it as follows when needed
.span {
font: $font-200;
p {
font: $font-100
}
}
If this is what you want, I am afraid as of now, this is not allowed