CSS
Let's finally learn this motherfucker. Perhaps my notes will be of use to you.
Forming opinions (take with a salt mine). Define "useless" to mean "I can more easily do this with script logic"
- Why use advanced selectors when I can differentiate with business logic instead? There are increasingly many selectors that permit differentiating elements (eg
:local-link) that could be known at first render time. If I'm making an obsidian publisher, I know which links are local and which ones aren't. Why wouldn't I just differentiate the styles (eg applied classes) there? Why use.list-item:last-of-typewhen I can use.list-item-last? - CMV: user-input pseudo selectors are the only ones I should give a shit about.
id's are useless
CSS is fucked up
My trauma dumpster.
Layout
Flexbox
If you can understand the following and answer all the questions, I think you will fundamentally understand flexbox.
Assume English (LTR) text direction for explanation.
Items are ordered along the direction of the main axis, which moves from flex-start to flex-end. The default order priority of all items is 0, which can be changed per-item with order: n.
When items can't fit on one line and wrap, lines (aka contents) are the rows (or columns) of items. The line direction is the same as the main-axis.
- flex-direction. Sets main axis direction relative to text direction.
rowis left-to-right. - flex-wrap. Should we wrap content into multiple lines? If yes, are the lines ordered from top-to-bottom (
wrap) or bottom-to-top (wrap-reverse)? If no,align-contentdoesn't make sense, because there is only one line in the flexbox.- Test your understanding: with
flex-flow: row wrap-reverse, you can think of the lines as items in a flexbox withflex-direction: column-reverse.
- Test your understanding: with
- justify-content. How do we position items within a line? We can define relative to main-axis (eg
flex-start) or how to space items (egspace-between).- Test your understanding: what values make sense for
justify-content? There are six.
- Test your understanding: what values make sense for
- align-items. Within a line, should items take up all the cross-axis space (
stretch), or if not, how should we position items along the line's cross-axis?- Test your understanding: what values make sense for
align-items? There are 3 other thanstretchandbaseline(using text baseline inside items).
- Test your understanding: what values make sense for
- align-content. If we have lines (aka
flex-wrapis notnowrap), should lines take up all space (stretch)? If not, how should we position the lines?- Test your understanding: what values make sense for
align-content? Hint: if you ignorestretch, the other values are the same as another flex property. - Test your understanding: with
flex-flow: wrap, if the lines were items, what would theflex-directionof this flex-box be? What would it be withflex-flow: wrap-reverse?
- Test your understanding: what values make sense for
Grid
Grids
- For a grid with 5 columns, it has 6 lines (indexed from 1 to 6).
- Use
grid-columns: 1em 30px 20% 20% 20%orrepeat(5,20%)or1fr 3fr(for 4 parts).frdivides the leftover space (after taking up20%,1em, etc)
grid-template: rows / columnsis a shorthand forgrid-template-rows: rows; grid-template-columns: cols
Items
- Explicit positioning
grid-column-{start,end}positions an item within a grid.- a pair of grid line indexes. The order doesn't matter, it's always from lowest to highest.
- one grid line index and
span n(how many columns to take up).
grid-column: i / jis a shorthand forgrid-column-start: i; grid-column-end: j.- You can also do
grid-column: i / span n!
- You can also do
grid-row,grid-row-startandgrid-row-endworks analogously to the column properties.grid-area: r1 / c1 / r2 / c2works likegrid-row: r1 / r2; grid-column: c1 / c2. I kinda hate the values order. I prefer to think of it as coordinates on the grid lines, likegrid-area: y1 / x1 / y2 / x2where the top-left corner is(1,1). Note that in RTL, the top-right is(1,1).
- Ordered positioning
- Children of grids are items, and are placed in DOM node order by default. As with flexbox, the default order priority is
0, and you can change it per item withorder: n.
- Children of grids are items, and are placed in DOM node order by default. As with flexbox, the default order priority is
Basics
Selectors
- element, id, class, attribute (ie
[href] { ... })- Attribute selectors seem vaguely useful for targeting eg links
- tied specificity (?) -> last selector wins
Specificity. Combinators don't change weight
id
> .class :pseudo-selector [attr-selector*='value']
> type-selector p ::pseudo-element p::first-letter
Box model
- sane, practical takeaways
- use lobotomized owl
* + *to set margins between adjacent elements (in flow content, which should be the majority of your content). then all other spacing should be controlled with padding
- use lobotomized owl
%% All elements, default %%
* + * {
margin: 1em;
}
%% Reduce the spacing for your menu %%
.menu * + * {
margin: 0.75em;
}
- box model definition
- content < padding < border < margin
total width = width + padding + border + margin
- margins and padding
- horizontal margins add the two, vertical margins max the two
- shorthands.
padding: top right bottom leftorpadding: top-bottom right-leftorpadding: top-bottom-right-left. also works for margin - centre something with
margin: 0px auto
- user agent stylesheets are the defaults that come with a browser. They often include default box properties (padding, margin) for all elements. You can reset these with
* { margin: 0; padding: 0; } display: noneremoves an element (reflows), whilevisibility: hiddenholds the space for it.- There are two ways of
box-sizing- border-box
- The sensible choice.
widthrefers to content and padding. Content width is calculated fromwidthandpadding-left,padding-right- #funfact border-box was implemented by IE against the CSS spec, but it's actually considered best practice now. IE lives on, lol.
- content-box
width, heightaffects content only- Only the default for legacy. A world of pain. Don't use it.
- border-box
Positioning
- position
- static: default, normal, flows
- relative: still flows, relative to static
- absolute: doesn't flow, relative to nearest parent relative
- fixed: relative to screen
- sticky: relative until certain spot, then fixed
z-indexdoes not work with static because the usual flow (fromstatic) prevents overlaps.- display
- inline elements are not separated by newlines, can't have width, height. They can still have padding and margins. Their content size is only determined by their content.
- block elements are separated by newlines
- float. Don't care. Use flex or grid.
Colour. Use hsl for ease of computing the arguments for colours that will give visual harmony.
Media queries
- As with regular CSS, last declaration wins. As such, if your base rules target mobile first (smallest screen-size), your subsequent media queries should be
@media (min-width: 600px) {},@media (min-width: 800px) {}, and so on. If your base rules target desktop first, you'll be usingmax-sizeinstead ofmin-size. - Also helpful:
@media (orientation: landscape),@media screen,@media print(custom rendering for printing, eg to add pages).