Estelle Weyl | @estellevw | Github | Press → key to advance.
--*
var(--*)
functionenv()
function--*
Property names that are prefixed with --
are custom properties
They contain a value that can be used in other declarations using the var()
function.
Custom properties are scoped to the element(s) they are declared on, and participate in the cascade. The main.css
file has global colors.
The five custom properties on the previous slide, --font, --dark_bg, --colorpop
, and --lightsplash
have been overwritten for this deck, thanks to "the cascade"
Custom properties are scoped to the elements they are declared on. What happen if we scope more locally and change the values of some properties?
Change the figure
to header
and change some values
Remove a line. If no value is set for a custom property on a given element, the value of its parent is used.
var(--*)
functionCustom properties containing values are used in declarations using the var()
function. Note property names are case sensitive
The var()
function can be used as a value in other functions
Internationalization
:root:lang(en-us) {--wedding: #FFFFFF;} :root:lang(hi-in) {--wedding: #CC0000;}
So you don't get bored staring at the same deck all day:
:root { --splashcolor: #880088; --dark_bg: #666666; }
OOoops, you thought you declared a custom property, but you didn't. No worries. Include fall backs.
color
will be red because colorpop
was misspelled.color: var(--colorpoop, red);
background-color
will be green because custom property names are case sensitivebackground-color: var(--colorpoop, var(--splashColor, green));
text-decoration-color
will be blue because '--colorpop, --splashcolor
' is not a valid custom property name.text-decoration-color: var(--colorpop, --splashcolor, blue);
Paragraph will be blue
body { color: red; } p { color: blue; } p { color: 16px; }
Syntax errors are ignored.
Paragraph will be red
:root {--size: 16px;} body { color: red; } p { color: blue; } p { color: var(--size); }
Invalid: custom property values that are invalid are not ignored. Value, if inheritable, is inherited
Paragraph will be red
:root {--size: 16px;} body { color: red; } p { color: blue; } p { color: var(--pooperscooper); }
If the value doesn't exist, it is invalid, and fails too. Not just invalid values, but non-existant properties.
SpecSpeak: Value computation (where variable references are resolved) happens after applying the cascade, which means that the `color: blue` declaration was already eliminated in favor of the variable reference.
When the browser encounters an invalid var() substitution, the initial or inherited value of the property is used.
If a variable substitution doesn’t make any sense, the browser:
While a syntax error in a CSS property / value pair will lead to the line being ignored, using a cascaded value, invalid substitution -- using a custom property value that is invalid -- is not ignored.
Variable references are resolved after applying the cascade, so a valid declaration may have been eliminated in favor of a variable reference without checking validity of that reference.
you can get the value just like you would any property value
// get a variable let heading = document.querySelector('.current header h1'); let headingColor = getComputedStyle( heading ).getPropertyValue( "--colorpop" );
Can be used to pass information to JavaScript
--forJS: if(count > 15) this.width = 100;
You can also use .style to read or write on an inline style, but since inline styles are not what I recommend, 😝
env()
functionenv()
functionenv()
functionFor inserting browser environment variable values
body { padding: env(safe-area-inset-top, 20px) env(safe-area-inset-right, 20px) env(safe-area-inset-bottom, 20px) env(safe-area-inset-left, 20px); }
calc()
calc()
syntaxTo perform calculations anywhere a <length>, <frequency>, <angle>, <time>, <percentage>, <number>
, or <integer>
value is allowed.
property: calc(expression)
Example:
height: calc(90vh - 100px);
calc()
computationsUse standard math:
calc( 6 * 2 / 3 - 4 + 5);
Use parenthese to make it less confusing
calc( 6 * (2 / 3 ) - (4 + 5));
calc()
rules<length>
syntax value, with or without units.calc()
in a calc()
is also AOKcalc()
inside a custom property is, you guessed it, AOK.calc()
examples:root { --widthA: calc(100% - 80px); --widthB: calc(var(--widthA) / 2); --widthC: calc(var(--widthB) / 2); }
min()
, max()
and clamp()
Can be used anywhere a <length>, <frequency>, <angle>, <time>, <percentage>, <number>
, or <integer>
is allowed.
min()
- only works in SafariSets the smallest (most negative) value from a list of comma-separated expressions.
max()
- only works in SafariSets the largest (most positive) value from a list of comma-separated expressions.
clamp()
- doesn't work anywhereClamps a value between an upper and lower bound: a middle value within a range of values between a defined minimum and maximum
font-size: max(4vw, 2em, 2rem);
max-height: min(40vh, 300px);
clamp()
- for the futureclamp( <minimum value>, <preferred value>, <maximum value>)
Those three values can be calculations, min() functions and max() functions as well
clamp(MIN, VAL, MAX)is resolved as
max(MIN, min(VAL, MAX))
Examples:
font-size: clamp(1rem, 4vw, 3rem); font-size: clamp(var(--smallFont), var(--userPref), var(--largeFont));
Trigonometric and exponential values
sin() cos() tan() asin() acos() atan() atan2() pow() sqrt() hypot()
Responsive font equation
font-size: calc( var(--min_font) + (var(--max_font) - var(--min_font)) * ( (100vw - var(--min_width)) / ( var(--max_width) - var(--min_width)) ));