Is it possible to change sass variable based on screen width? I want my $font-size to be 1.5rem on tablet and 1.4rem on mobile so my headings change dynamically.
I tried sth like this:
$font-size: 1.6rem;
#include respond(tab-big) {
$font-size: 1.5rem;
}
#include respond(mobile) {
$font-size: 1.4rem;
}
$font-size-heading: 4 * $font-size;
$font-size-subheading: 2 * $font-size;
Or is there any other way to make this code better:
$font-size: 1.6rem;
$font-size-tab: 1.5rem;
$font-size-mobile: 1.4rem;
$font-size-heading: 4 * $font-size;
$font-size-subheading: 2 * $font-size;
$font-size-heading-tab: 4 * $font-size-tab;
$font-size-subheading-tab: 2 * $font-size-tab;
$font-size-heading-mobile: 4 * $font-size-mobile;
$font-size-subheading-mobile: 2 * $font-size-mobile;
For dynamic changing font sizes you could use the css clamp(min value, dynamic unit, max value) function.
[Kevin Powell did a nice Video on this][1]https://www.youtube.com/watch?v=U9VF-4euyRo
a sass way to further edit this function would be to set the fontsize with a clamp fuction and put in variables.
/*scss*/
#mixin dynamicFontSize ($a) {
font-size: clamp(10px * $a, 2vw * $a, 20px * $a);
}
#include dynamicFontSize (2);
/*or*/
#include dynamicFontSize (0.7);
for this soution you have to tinker a bit with the units but when you got it its awesome.
Related
I am getting "Incompatible units: 'rem' and 'px'" when overriding the Bootstrap 4.3.1 variables in a custom override sass file.
I have tried positioning following paths on custom sass file on top of the file and last line of the file as instructed on Bootstrap 4 documentation.
#import "node_modules/bootstrap/scss/functions";
#import "node_modules/bootstrap/scss/variables";
#import "node_modules/bootstrap/scss/mixins";
Error in terminal
ERROR in ./src/scss/main.scss (./node_modules/raw-loader!./node_modules/postcss-loader/lib??embedded!./node_modules/sass-loader/lib/loader.js??ref--14-3!./src/scss/main.scss)
Module build failed:
$custom-select-feedback-icon-padding-right: calc((1em + #{2 * $custom-select-padding-y}) * 3 / 4 + #{$custom-select-padding-x + $custom-select-indicator-padding}) !default;
^
Incompatible units: 'rem' and 'px'.
Remove <br> from the SCSS file first and this the problem of calc() function not the problem of px or rem.
NOTE
calc() function is the inbuilt function of CSS, so whenever you call calc() in SCSS, you need to use #{} technique to use the variable
height: calc(100% - #{$body_padding})
Now I give you one example
$custom-select-padding-y = 50px;
$custom-select-feedback-icon-padding-right: calc((1em + #{2 * 50px}) * 3 / 4 + #{$custom-select-padding-x + $custom-select-indicator-padding}) !default;
2 * 50px = 100px and so on after that, it cant calculate 1em + {random px} so, its return undefined and compiler give error.
calc() calculates 2 * 5px = 10px or 2 * 1rem = 32px.
calc() cant calculate 2rem + 1em, 1rem + 1px etc.
I've spent the past 4 hours trying to find a way to create a sprite image with Compass and sass that also automatically scales each individual image for use with the background-size property.
Nothing I've found works, can't believe it's that difficult.
Does any one have a working example?
Edit: This is what I have so far
#mixin resize-sprite($map, $sprite, $percent) {
$spritePath: sprite-path($map);
$spriteWidth: image-width($spritePath);
$spriteHeight: image-height($spritePath);
$width: image-width(sprite-file($map, $sprite));
$height: image-height(sprite-file($map, $sprite));
#include background-size(ceil($spriteWidth * ($percent/100)) ceil($spriteHeight * ($percent/100)));
width: ceil($width*($percent/100));
height: ceil($height*($percent/100));
background-position: 0 floor(nth(sprite-position($map, $sprite), 2) * ($percent/100) );
}
#mixin resize-sprite-set($map, $percent, $only...) {
$name: sprite_map_name($map);
#each $sprite in sprite_names($map) {
#if length($only) == 0 or index($only, $sprite) != false {
.#{$name}-#{$sprite} {
#include resize-sprite($map, $sprite, $percent);
}
}
}
}
The mixin returns no errors.
$my-icons-spacing: 10px; // give some space to avoid little pixel size issues on resize
#import "my-icons/*.png";
$my-icons-sprite-dimensions: true;
#include all-my-icons-sprites;
// the fun part
.small-icons { // overriding all sprites
#include resize-sprite-set($my-icons-sprites, 40); // 40% sized
}
.some-part-of-my-site {
#include resize-sprite-set($my-icons-sprites, 40, logo, ok); // will create overrides only for sprites "logo" and "ok"
}
I get the following error message from the above implementation when I try to compile. Via Prepros App.
remove ../images/my-icons-s9e77ab1ef1.png
create ../images/my-icons-s9e77ab1ef1.png
error style.scss (Line 62 of _mixins.scss: Undefined mixin 'resize-sprite-set'.)
identical ../css/style.css
I've also done some research on this. This gist is what I came up with:
https://gist.github.com/apauly/7917906
Update:
The solution depends on three key-parts:
scale width
scale height
get background-position
0.
Grab the dimensions for both, the complete sprite and the single icon:
$icon-file: sprite-file($map, $icon);
$icon-width: image-width($icon-file);
$icon-height: image-height($icon-file);
$sprite-file: sprite-path($map);
$sprite-width: image-width($sprite-file);
$sprite-height: image-height($sprite-file);
1.
Consider a div displaying a sprite as its background. Set background-size: 100%; to make sure, that the background sprite covers the full width of the div.
If one would use width: 100%;, the result would be something like this:
+----------------+
|--| |
|----------------|
|--------| | <--- This is the sprite image we want to display
|------| |
+----------------+
So we need to enlarge our background to get something like this: (the div should have overflow:hidden though)
+----------------+
|---------| |
|-----------------------|
|----------------| | <---
|-------------| |
+----------------+
To achieve that, just divide the width of the complete sprite by the width of the single icon:
width:percentage($sprite-width / $icon-width);
2.
This one is basically inspired by a blog post form tkenny:
http://inspectelement.com/tutorials/a-responsive-css-background-image-technique/
The resulting sass code is this:
display: block;
height: 0;
padding-bottom: percentage($icon-height / $icon-width);
background-size: 100%;
3.
The rest is just some basic math to calculate the top spacing of the icon inside of the sprite as a relative value:
Get the space from the top in pixels (a negative value):
$space-top:floor(nth(sprite-position($map, $icon), 2));
Sass will need a px-value
#if $space-top == 0 {
$space-top: 0px
}
Set the background position with percentages:
background-position:0 percentage(
-1 * $space-top / ( $sprite-height - $icon-height )
);
Here's a mixin for resizing sprites that works beautifully
#mixin resize-sprite($map, $sprite, $percent) {
$spritePath: sprite-path($map);
$spriteWidth: image-width($spritePath);
$spriteHeight: image-height($spritePath);
$width: image-width(sprite-file($map, $sprite));
$height: image-height(sprite-file($map, $sprite));
#include background-size(ceil($spriteWidth * ($percent/100)) ceil($spriteHeight * ($percent/100)));
width: ceil($width*($percent/100));
height: ceil($height*($percent/100));
background-position: 0 floor(nth(sprite-position($map, $sprite), 2) * ($percent/100) );
}
and the github it came from:
https://gist.github.com/darren131/3410875
I am new to SASS and Compass trying to create one function which can convert passed pixel value to em. I found one tutorial but it is for SCSS and that doesn't work with SASS.
Even I have checked on SASS website but seem they have most document for SCSS and not everything they have describe for SASS.
Here what I am writing
#function em($px, $base: 24px)
#return ($px / $base) * 1em
Also using vertical-rythem in my project and tried this to but than again giving error for $base-font-size
#function em($px, $base: $base-font-size)
#return ($px / $base) * 1em
So when I use it as
font-size: em(16px)
It should convert to 1em in output
The function you have seems correct. Just make sure you have defined $base-font-size with a value such as 16px.
The above mixin you have should also work
$base-font-size: 16px;
#function em($px, $base: $base-font-size) {
#return ($px / $base ) * 1em;
}
Now you can call font-size: em(16px); and it should work
You can also call this function with an optional base, sometimes you might want to calculate on a base that's not 16px.
Please also look up http://css-tricks.com/snippets/css/less-mixin-for-rem-font-sizing/ for rem font sizing. You might want to skip em because they have a nesting problem http://css-tricks.com/why-ems/
For a more detailed version of the above mixin, where you can call
border: emCalc (10 20 30 40);
Where you don't have to repeat the px value again and again and you may have 1 to 4 values within, check the mixin in Zurb's foundation _global.scss
https://github.com/zurb/foundation/blob/master/scss/foundation/components/_global.scss#L183
Is it possible to override the default gutter value for a container with base values e.g. like that:
$total-columns: 12;
$column-width: 60px;
$gutter-width: 20px;
$grid-padding: 10px;
So that you would be able to minimize the gutter from 20px to e.g. only 5px, or any other desired value, on demand.
.example{
#include squish(1,1);
li{
#include span-columns(2,10);
#include nth-omega(5n);
}
}
Is it possible via a mixin, would i have to place another container/layout or should i stick with plain CSS to solve that task? Thanks
Update:
To be more specific, i don't look for an exact sizing of the gutter (as far as i read so far, due to rounding, it would be difficult anyway), i just want to minimize the gutter and enlarge the column width indirectly.
https://dl.dropbox.com/u/8578/Boxes.png
At the moment i have squished 3 columns before and after the contained 7 columns and their gutters. So far the columns and its images are too small in width. Therefor i wanted to size down the gutter width and enlarge the column width indirectly.
The Susy settings look that way:
$total-columns: 24;
$column-width: 3%;
$gutter-width: 1%;
$grid-padding: 0;
A container width i haven't set so far since the container is inside a wrapper for the whole page.
.wrapper {
#include container;
overflow-x: hidden;
width:100%;
max-width: 100%;
}
The specific selector for the image matrix shown in the screenshot is the following:
.projects {
#include squish(3,3);
li {
#include span-columns(2,14);
#include nth-omega(7n);
}
}
You need any more details? So would you still recommend to use the with-grid-settings mixin to solve that problem? And is the set-container-width mixin really necessary? Thought if i set up things relative no absolute values should be necessary? Thanks Ralf
Update 2:
Ufff i tried the suggested little secret's approach mentioned in the comments beneath. But so far i was unable get a clean display, more like a messy chaotic "patchwork"... ;) Kind of confusing over all. Basically the articles author recommended 2 steps. First he added -100% margin-right for the content containing element and in the next step pushed the objects back into their places. My last setup in a long line of tries looks like that right now but still no solution in sight.
.example{
#include squish(3,3);
#include with-grid-settings($gutter: 0.1%){
margin-right: -100%;
li{
#include span-columns(6,18);
#include nth-omega(3n);
#include pre(9);
}
}
}
The margin-right i've placed within the with-grid-settings mixin in the containing element for "li" like suggested. But the question is where to place the pre mixin and especially which numbers it should contain (has the number to take the squish number in consideration too)? Is it the same value for all li or is a for loop necessary to push the images to individually to their horizontal positions ? And is the mixin order within the li element correct? Does it matter where it is placed? At the end or inbetween span-columns and nth-omega? Over all i am still confused. Grids, image matrices and Susy still keep my brain spinning. :/
Update 3:
Thanks! I finally got it working. In the end i would have two questions about my solution:
.test{
#include with-grid-settings($gutter: 0.1%){
li{
margin-right: -100%;
float:left;
#include span-columns(6,18);
#include nth-omega(3n);
$count:0;
#for $i from 1 through 9 {
&:nth-child(#{$i}) {
$count: $count + 1;
#include push($count);
#if $count == 2{ $count: 0;}
}
}
}
}
}
Would there be a more elegant way for the layout of the for loop? And second why is it possible that this version as well as a version when i comment out the $count: $count + 1; statement lead to the same visual result? Actually commented out there isn't a second and third count up for the push variable. Any idea why that works anyway without the $count: $count + 1;? Thanks!
Update 4:
I played around a little bit more and as it turns out the following version works like a charm. It seems the $count variable isn't necessary at all, as well as the incremental growing of the value contained within the push/pre mixin. A simple 0 did the trick.Thanks again for the help!!!
.test{
#include with-grid-settings($gutter: 0.5%){
li{
margin-right: -100%;
#include span-columns(6,18);
#include nth-omega(3n);
#for $i from 1 through 9
{
&:nth-child(#{$i})
{
#include push(0);
}
}
}
}
}
Update 5
I already mentioned in my last comment beneath that the example shown in update 4 hasn't worked as good as it supposed to work at the first look. I tried now to completely rebuild the suggestion from the Palantir article. Underneath is the scss parts for the 7x4 as well as the 3x3 matrix shown in the video: https://dl.dropbox.com/u/8578/matrix.mov
.7x3{
#include with-grid-settings($gutter: 0.25%){
li{
margin-right: -100%;
#include trailer(1);
#include span-columns(2,14);
#include nth-omega(7n);
$y: 0;
#for $x from 1 through 28
{
&:nth-child(#{$x}){
margin-left: ($y * columns(2,14)) + ($y * gutter(14));
$y: $y + 1;
#if $y > 6{
$y: 0;
}
}
}
}
}
}
.3x3{
#include with-grid-settings($gutter: 1%){
li{
margin-right: -100%;
#include trailer(1);
#include span-columns(6,18);
#include nth-omega(3n);
$j: 0;
#for $i from 1 through 9
{
&:nth-child(#{$i}){
margin-left: ($j * columns(6,18)) + ($j * gutter(18));
$j: $j + 1;
#if $j > 2{
$j: 0;
}
}
}
}
}
}
At the first look the matrices look broken but if you take a closer look at the inspector within the video, it appears that each element is pushed to its correct horizontal position in both matrices. Only problem is that each li is contained in separate lines. This is the closest version i was able to get. :/ Right now i am out of ideas how to put those pieces together to get to a proper matrix. I tried more or less ever possibility with float as well as display properties. But no luck. Anyone has a hint perhaps?
You can use with-grid-settings() (reference docs) to wrap your code:
Since you don't want to change the actual container width, we can leave that alone. It's up to you if you want the .projects padding (from squish()) to be influenced, but I'm going to assume you don't. Here it is, just changing the $gutter-width for the lis:
#include with-grid-settings($gutter: .5%) {
li {
#include span-columns(2,14);
#include nth-omega(7n);
}
}
That's it. If you do want anything else to use the adjusted settings, simply move them inside the mixin.
This question already has answers here:
Adding a unit to a number in Sass
(2 answers)
Closed 7 years ago.
I am quiet new to Sass... I want to create some css with percentage values like:
width : 13%;
The value is the result of a sass number operation. Writing this
width : $main-width + "%"
scss code generates this:
width : "13%";
css, what is actually not working because it should be:
width : 13%;
writing
width : $main-width %;
results in
width : 13 "%"
what also leads to a non working css-rule. Is there a way to make Sass print 13% plain, with no quotes?
Think of units in Sass like variables in algebra instead of just concatenating strings.
In algebra:
2x * 3 = 6x
In Sass:
13 * 1% = 13%
Use this approach to do more advanced math.
10px * 3px = 30px*px
But px*px isn't a valid CSS unit so you have to cancel one out by dividing by 1px
30px*px / 1px = 30px
Hope this helps beyond your original question.
unquote("%") does the trick.
You could try #.
I had a similar problem with a mixin and lists
#mixin p($value, $position: a, $unit: $rhythm-unit){
$vallist: ();
#if length($value) > 1 {
#each $sval in $value {
$sval: 0 !default;
$vallist: append($vallist, #{$sval}#{$unit});
}
padding: $vallist;
} #else{
#if $position == t {
padding-top: $value+$unit;
} #else if $position == r {
padding-right: $value+$unit;
} #else if $position == b {
padding-bottom: $value+$unit;
} #else if $position == l {
padding-left: $value+$unit;
} #else {
padding: $value+$unit;
}
}
}
The problem was
append($vallist, $sval+$unit);
It always added quotes around these values e.g. "1rem" "1.25rem" which is not a correct css syntax.
I replaced it with:
append($vallist, #{$sval}#{$unit});
As you can see i use #-sign with {} and + it not necessary any more.
The very interesting here is that this only appear with lists/append as you can see in my outer else.
You could find it at the sass reference page Division and slash
If you want to use variables along with a plain CSS /, you can use #{} to insert them. For example:
p {
$font-size: 12px;
$line-height: 30px;
font: #{$font-size}/#{$line-height};
}
Hope it helps