Joshua's Cheatsheets
Light
help

CSS and General Styling - Cheatsheet

Different frameworks and tools

Cheatsheet

CSS Transitions

Syntax:

div {
    transition: <property> <duration> <timing-function> <delay>;
}

Example:

div {
    transition: all 2s ease 1s;
}

Extracting CSS

Kind of weird that this isn't baked into browsers, although it looks like it was supposed to be at some point. There are browser extensions though, like Snappy Snippet.

Globals, variables, and theming

Can I use: Browser Support. Note that IE 11 has no support. You can use something like webpack to transform the dynamic variables refs into static. See this. Or you can simply define the CSS value twice, first with a non-variable value that will be the fallback, and then with the variable. On older browsers it should just use the non-variable fallback.

CSS variables (more accurately custom properties) are notated with a double-dash prefix. You can declare them at multiple levels, and are inherited from parents (scoped).

CSS:

.vendorWidget {
    --primaryColor: red;
    --secondaryColor: blue;
}
.vendorButton {
    background-color: var(--primaryColor);
}

HTML:

<div class="vendorWidget">
    <button class="vendorButton">Click Me!</button>
</div>

To emulate theming, a common approach is to declare global variables at the highest level. In CSS, there is a trick you can use instead of guessing the element with the highest specificity: just target :root. (MDN).

:root {
    --loosePaddingPx: 14px;
    --tightPaddingPx: 4px;
    --primaryColor-light: #BEFFFF;
    /* You can mix vars and non-vars */
    background-color: red;
}

Fallbacks:

You can define a fallback in case a variable is undefined:

.myButton {
    background-color: var(--myVar,red);
}

If you want to try a few different vars, and keep falling back if undefined, you can nest them:

.myButton {
    background-color: var(--myVar,var(--secondaryVar,red));
}

Note that fallbacks are not the same as polyfilling or providing defaults for if a browser does not support custom properties. You can use a polyfill library to do that, or repeat each property twice, first with a default fallback, and then with the variable, like so:

.myButton {
    background-color: red;
    background-color: var(--myVar,var(--secondaryVar,red));
}

Theme Switching

There are a bunch of ways to accomplish this. I've written up a comprehensive exploration of options at https://joshuatz.com/posts/2019/coding-a-css-theme-switcher-a-multitude-of-web-dev-options/

Accessing with JavaScript:

// This will target :root variables
document.querySelector(':root').style.setProperty('--myColor',newColor);
// Or, same thing...
document.documentElement.style.setProperty('--myColor',newColor);

Sass/Scss


Targeting the first element of something

First child, regardless of type

Use the :first-child pseudo class / selector.

.parent div:first-child {
    border-top: 1px solid black;
}
.parent div {
    border-bottom: 1px solid black;
}

The above code is nice because it gives both top and bottom borders to only the first element, and then bottom borders to the rest. If I added top and bottom to all children, then elements after the first would end up with double borders (the tops and bottoms would combine).

Note: this requires that the targeted element is a direct child of the parent selector

First child of certain element type

If we have a bunch of mixed element types, first-child would both not make sense, and might not work too. Consider this kind of setup:

<div class="root">
    <div class="abcd">
        <div>I'm the first child of abcd</div>
        <!-- Element below is my actual target -->
        <span class="target">Hello</span>
    </div>
    <span class="target">World.</span>
    <span class="target">How are you?</span>
</div>
<style>
.target {
    background-color: blue;
}
</style>

Let's say I wanted to make the first <span> have a red background, but all the rest have blue. I can't use first-child, because it is not the first child of div.abcd. I could use the nth-child() rule, like .abcd .target:nth-child(2) { background-color: red; }, but that would require that the order always stay the same. What if I add another div in front of it?

A better option is the newer :first-of-type pseudo selector:

.abcd span:first-of-type {
    background-color: red;
}

Note that by type, the rule is referring to the type of element, not a selector. If you try to do something like abcd .target:first-of-type, it won't work, because .target is a class selector, not a type of element.


Unusual / Fun selectors to remember

Code What Notes
div[data-ref*="23"] Attribute Selector See "Attribute Selector Cheatsheet" below

Attribute Selector Cheatsheet

Full list and details on MDN.

Short Practical Example What
{elem}[attr] or [attr] script[async] Matches any input that has attribute of id, regardless of value
[attr="value"] script[src="https://www.google-analytics.com/analytics.js"] Attribute must exactly match value
[attr*="value"] script[src*="analytics"] Attribute must contain value
[attr~="value"] [data-color-scheme~="red"] Attribute must be a string of whitespace separated words, and the value must exactly match one of them.
[attr^="value" script[src^="https://www.google-analytics.com"] Attribute must start with exact value
[attr$="value"] script[src$="analytics.js"] Attribute must end with exact value
[attr|="value"] script[src|="https://www.google"] A little odd. Attribute must either exactly match, or start with value and be immediately followed by hyphen (-)

Note: You can add i before the closing brackets to force a case insensitive match. Like: script[src*="gOOgle"i]

Note: You can target by any attribute, including value. This has led to a notable CSS-only hack (HN) that can listen for specific characters and report back to an external server (bad for password fields!). Note, this only works if JS is updating the value attribute as the user types. In an "uncontrolled" field, this doesn't work.

Question: [attr~="val"] vs [attr*="val"]

Since the description for [attr~="val"] can be a little confusing, here is a very simple demonstration of its difference and the value it brings - a table of matches:

DOM [animals*="cat"] [animals~="cat"]
<div animals="dog cattle bird"> Yes No
<div animals="dog cat bird"> Yes Yes

CSS Animations

@TODO

Markdown Source Last Updated:
Wed Nov 13 2019 08:09:02 GMT+0000 (Coordinated Universal Time)
Markdown Source Created:
Mon Aug 19 2019 17:06:24 GMT+0000 (Coordinated Universal Time)