I want to be able to access the value of each break point set in the $grid-breakpoints variable. It is laid out like this:
$grid-breakpoints: (
xs: 0,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px
);
In previous versions, the breakpoints were laid out like
$screen-md: 768px;
and so having something like width: $screen-md would produce width: 768px (or whatever the medium width is).
Now in BS4, I don't see how to do this. When I try using $grid-breakpoints as my variable - it breaks because the variable is pulling in all of those as one value.
Does that make sense what I'm trying to do? How can I do it?
Use map-get like:
map-get($grid-breakpoints, "md")
Demo: https://www.codeply.com/go/31V8zhXAO5
Related
The SCSS #forward rule supports a couple nice features:
#forward './colors' show $red, $green, $blue; will only forward $red, $green, and $blue from ./colors. All other values that ./colors would otherwise export are ignored.
#forward 'library' with ($space: 2em); will make $space available to the library, overriding any default that library may have for $space.
How can I use these both together? In my case I'm using the include-media library. I want to define a module that wraps it like this (slightly simplified):
#forward 'include-media with (
$breakpoints: ( 'small': 400, 'medium': 700, 'large': 1000 )
) show media, media-context;
The goal here is to both provide the library the $breakpoints value it's expecting, and forward only the media and media-context mixins. Unfortunately that code fails to compile with this error:
Error: expected ";".
╷
3 │ ) show media, media-context;
│ ^
I get similar results if I put the show clause before the with clause.
It seems sub-optimal, but I could imagine this working with two files:
// file _withBreakpoints.scss
#forward 'include-media' with (
$breakpoints: ( 'small': 400, 'medium': 700, 'large': 1000 )
);
// file _filtered.scss
#forward './withBreakpoints' show media, media-context;
Surely there's a better way?
I checked that and cannot confirm the issue. (Tested with Compiler: VS Code extension Live SASS by(!) Glenn Marks).
But important: hide/show must be called BEFORE with.
Following syntax works here (just examples):
//### forward with hide
#forward 'variables' hide $color_red with(
$color_orange: yellow,
$color_gray: magenta,
);
//### forward with show
#forward 'variables' show $color_red with(
$color_red: orange,
);
But there seems to be some other issues in your code:
You try to #forward a module only showing media, media-context (that are the only members which are forwarded) but you try to change variable $breakpoints which is not shown/forwarded because it is not in the list.
Just as polite guessing (not knowing): You want to show/forward media, media-context. Are that functions/mixins? If var you should write them with $.
You missed the closing quote after the forwarded file: #forward 'include-media ...
So, maybe you like to try something like this:
#forward 'include-media'
show [$?]media, [$?]media-context, $breakpoints
with (
$breakpoints: ( 'small': 400, 'medium': 700, 'large': 1000 ),
);
//### Think about 'show':
//### What is not in the list is not fowarded and cannot be used.
//### So I am not sure ...
//### if your module needs more members to be forwarded so it works.
//### Depends on your module.
How does one define variables with the use of other variables in SASS?
This is how one could do it with LESS:
// import Google Material Colors
// returns variables ie #blue-500, #blue-400 etc
#import 'material.colors.less';
// base
#_color: 'blue';
#_secondary: 'amber';
// primary colors
#color-primary: ~"#{#{_color}-500}";
#color-primary-bright: ~"#{#{_color}-300}";
#color-primary-brighter: ~"#{#{_color}-200}";
#color-primary-brightest: ~"#{#{_color}-50}";
// secondary colors
#color-secondary: ~"#{#{_secondary}-500}";
#color-secondary-bright: ~"#{#{_secondary}-300}";
#color-secondary-brighter: ~"#{#{_secondary}-200}";
#color-secondary-brightest: ~"#{#{_secondary}-50}";
The LESS-way certainly isn't clean and dandy, but -- it works™
The idea is to set a base primary and then just set the other color(s) dynamically based on that.
I can't imagine that one would have to loop/map etc just to do this with SASS?(!)
Sass does not support dynamic variables, period.
You will need to use maps, but I'm not sure this will help you in this specific case (as you are already using external colors):
#import 'material.colors';
$colors: (
primary: (
default: $blue-500,
bright: $blue-300,
brighter: $blue-200,
brightest: $blue-50
),
secondary: (
default: $amber-500,
bright: $amber-300,
brighter: $amber-200,
brightest: $amber-50
)
);
#function color($color, $brightness: default) {
#return map-get(map-get($colors, $color), $brightness);
}
h1 {
color: color(primary, bright);
background-color: color(secondary);
}
Of course you can do it. You can use neat sass color functions and do what you need in a nice and clean way. Take a look at lighten function and even darken function, or at other color functions in general.
Basically, you do it like this:
$primary-color: #08f;
$primary-light-color: lighten($primary-color, 20%);
$primary-lighter-color: lighten($primary-color, 30%);
$primary-dark-color: darken($primary-color, 20%);
$primary-darker-color: darken($primary-color, 30%);
You can see this in action here:
https://codepen.io/anon/pen/PjXRjM?editors=1100#0
Or if you feel like it's a good idea, you could automate it a little with lists and loops. Take a look at this article: https://www.sitepoint.com/managing-color-values-with-sass/, where its author gets through it. (To be honest, I'm not sure if that a good idea at all, as it easily may be hard to understand and maintain later. That's another topic, though.)
I've been introduced to the gridlover tool. It provides SASS variables like:
$scale0: (
fontSize: 1em,
line: 1.5em,
autoLineCount: 1,
autoLineHeight: 1.5em
);
But I can't figure out what all the values correspond to.
I understand that I can use each one using map-get. fontSize is obviously used to set font-size and line looks like line-height.
.some-class {
font-size: map-get($scale0, fontSize);
line-height: map-get($scale0, line);
}
But what are autoLineCount and autoLineHeight? Are these SASS keywords? What am I suppose to do with them?
When creating a color scheme in SASS what's the conventional variable names for defining colors?
I know using color names are bad. Such as:
$blue
$red
$green
But I've not seen an alternative. I'm struggling for variable names for colors on the site that convey meaning.
Any ideas?
I found another idea in "SASS & Color Variables" article. The solution suggested by Sacha Greif is to use some variables to store descriptive color names, and some other to assign those colors to their functions:
// first we set descriptive variables:
$darkgrey: #333333;
$blue: #001eff;
// then we set functional variables:
$text_color: $darkgrey;
$link_color: $lightblue;
$border_color: $lightblue;
.myClass {
color: $text_color;
border-color: $border_color;
}
a {
color: $link_color;
}
I'm just beginning with SASS and don't know which approach is more practical, but I like the way it separates colors from their function.
In my personal experience the most useful way to name colors is to do it in regards of the color's function, such as
$background
$contrast
$text
$aside
$link
And so on. Of course which colors and name may depend on the design.
Then you may have different and exchangeable color schemes defined on different styles, such as:
_dark_scheme.scss
_light_scheme.scss
_pastels.scss
The idea here, is that you can use the same color variables in your main stylesheets, and do not depend on specific colors.
I like the idea of combining generic to specific naming (good for code completion) and description/functional naming. So you have something like this:
// Descriptive naming
$color-gray-light: #f3f3f3;
$color-gray-dark: #999999;
$color-red: red;
// Functional naming
$link-color: $color-red;
$link-border-color: $color-gray-light;
You can even create a mixin for greys (in the example RGBA is used for transparency, for example black on a red background would be more visible if it is 80% transparent black rather than dark grey).
#mixin grey($intensity: 0.5, $type: color) {
#{$type}: rgba(black, $intensity);
}
.i-am-50-percent-gray {
#include grey(0.5, color);
}
Give the result
.i-am-50-percent-gray {
color: rgba(0, 0, 0, 0.5);
}
I want to be able to do the following:
height: 25% - 5px;
Obviously when I do that I get the error:
Incompatible units: 'px' and '%'.
Sass cannot perform arithmetic on values that cannot be converted from one unit to the next. Sass has no way of knowing exactly how wide "100%" is in terms of pixels or any other unit. That's something only the browser knows.
You need to use calc() instead. Check browser compatibility on Can I use...
.foo {
height: calc(25% - 5px);
}
If your values are in variables, you may need to use interpolation turn them into strings (otherwise Sass just tries to perform arithmetic):
$a: 25%;
$b: 5px;
.foo {
width: calc(#{$a} - #{$b});
}
There is a calc function in both SCSS [compile-time] and CSS [run-time]. You're likely invoking the former instead of the latter.
For obvious reasons mixing units won't work compile-time, but will at run-time.
You can force the latter by using unquote, a SCSS function.
.selector { height: unquote("-webkit-calc(100% - 40px)"); }
$var:25%;
$foo:5px;
.selector {
height:unquote("calc( #{$var} - #{$foo} )");
}
IF you know the width of the container, you could do like this:
#container
width: #{200}px
#element
width: #{(0.25 * 200) - 5}px
I'm aware that in many cases #container could have a relative width. Then this wouldn't work.
Sorry for reviving old thread - Compass' stretch with an :after pseudo-selector might suit your purpose - eg. if you want a div to fill width from left to (50% + 10px) of screen you could use (in SASS indented syntax):
.example
background: red
+stretch(0, -10px, 0, 0)
&:after
+stretch(0, 0, 0, 50%)
content: ' '
background: blue
The :after element fills 50% to the right of .example (leaving 50% available for .example's width), then .example is stretched to that width plus 10px.
Just add the percentage value into a variable and use #{$variable}
for example
$twentyFivePercent:25%;
.selector {
height: calc(#{$twentyFivePercent} - 5px);
}