You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -90,7 +90,7 @@ Now we just need to ensure each element, the sidebar and the non-sidebar, grows
The reason for this high value is to ensure the non-sidebar takes up all of the free space wherever the two elements are adjacent. The sidebar's `flex-basis` value is not counted as free space and is subtracted from that calculation.
Here's something that's nice: that `max-width: 50%` declaration? It refers to the parent element's width, _not_ the viewport width. This makes the behavior more like that of a so-called 'container query' than a traditional media query. Container queries are still being specified and so far haven't been adopted by browsers. Here, we've kind of mimicked the _behavior_ of a container query without using anything like a JavaScript polyfill.
Here's something that's nice: that `min-width: 50%` declaration? It refers to the parent element's width, _not_ the viewport width. This makes the behavior more like that of a so-called 'container query' than a traditional media query. Container queries are still being specified and so far haven't been adopted by browsers. Here, we've kind of mimicked the _behavior_ of a container query without using anything like a JavaScript polyfill.
What if we want a margin between our sidebar and non-sidebar? If we add a margin to the sidebar's right-hand side, we solve the problem for contexts where the two elements are adjacent. Things get weird and gross when the non-sidebar wraps...
Heydon
revised
this gist Jan 1, 2019.
1 changed file
with
1 addition
and
3 deletions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -8,15 +8,13 @@ This unicode point, representing the humble space character, is between every wo
Before getting into flexible containers, viewport meta tags, and `@media` breakpoints _this_ humble character is what makes the web fundamentally 'responsive'. That is: able to change the layout of its content to suit different devices, contexts, and settings. Browser text does this automatically because it's kind of self-aware, just not self-aware in the scary Terminator/Skynet way.
Responsive content can be expressed mathematically. Take a `<div>`element and fill it with some text. If the width of that element is constant, the height will be whatever is needed for the element to accommodate the area the text takes up. If you increase the width of the element, the height diminishes accordingly.
Responsive content can be expressed mathematically. To _find_ the height of an element, you divide the area by the width. To find the width, you divide the area by the height. Given a `<div>` that is `50rem` wide and `25rem` high, if I reduce the width to `25rem`, the height will have to grow to `50rem` to still contain the same amount of text.
```js
height == area / width
width == area / height
```
To _find_ the height of an element, you divide the area by the width. To find the width, you divide the area by the height. Given a `<div>` that is `50rem` wide and `25rem` high, if I reduce the width to `25rem`, the height will have to grow to `50rem` to still contain the same amount of text.
In responsive design, we capitalize on the text wrapping algorithm by refusing to hard code widths and heights — letting our elements, and the text and media they contain, fill the available space. The vastly inferior alternative is to take inventory of all our users' device types and settings, tailoring specific, fixed designs to each. This is sometimes known as 'adaptive' design, or simply: _b******s_.
But even with flexible layouts, we still sometimes have to intervene and 'manually override' the layout process using `@media` breakpoints.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
You are looking at the most important, and most _abundant_ thing on the web. You can't see it, unfortunately, because it's very small… aaaaand it's invisible — so having a magnifying glass doesn't really help here. But still.
I'm talking, of course, about `U+0020`; not to be confused with the band U2, who are just as ubiquitous, but far less useful.
This unicode point, representing the humble space character, is between every word, in every run of text, on every page of the web. And it has a very special characteristic: _it's not sticky like glue_. If two words are neighbors but there's not enough room for both of them, the space will free the second word to wrap around and start a new line.
Before getting into flexible containers, viewport meta tags, and `@media` breakpoints _this_ humble character is what makes the web fundamentally 'responsive'. That is: able to change the layout of its content to suit different devices, contexts, and settings. Browser text does this automatically because it's kind of self-aware, just not self-aware in the scary Terminator/Skynet way.
Responsive content can be expressed mathematically. Take a `<div>` element and fill it with some text. If the width of that element is constant, the height will be whatever is needed for the element to accommodate the area the text takes up. If you increase the width of the element, the height diminishes accordingly.
```js
height == area / width
width == area / height
```
To _find_ the height of an element, you divide the area by the width. To find the width, you divide the area by the height. Given a `<div>` that is `50rem` wide and `25rem` high, if I reduce the width to `25rem`, the height will have to grow to `50rem` to still contain the same amount of text.
In responsive design, we capitalize on the text wrapping algorithm by refusing to hard code widths and heights — letting our elements, and the text and media they contain, fill the available space. The vastly inferior alternative is to take inventory of all our users' device types and settings, tailoring specific, fixed designs to each. This is sometimes known as 'adaptive' design, or simply: _b******s_.
But even with flexible layouts, we still sometimes have to intervene and 'manually override' the layout process using `@media` breakpoints.
For example, a sidebar can only be a sidebar if there's room for one. Where there's no room for two adjacent elements, they must be placed one atop the other. Employing a breakpoint at, well, the point of breakage, is the standard solution.
```css
@media (max-width: 20rem) {
.sidebar, .not-sidebar {
width: 100%;
float: none;
}
}
```
But the CSS Flexbox module lets us solve this problem algorithmically instead — without the need for breakpoints.
What makes a sidebar? Visually, an adjacent element that takes up less horizontal space than its neighbor. Therefore, the rule (or 'axiom') that underlies the layout is that the sidebar's companion should never be less than `50%` in width:
```css
.not-sidebar {
min-width: 50%;
}
```
As for the sidebar itself, we give that a `flex-basis` of something like `20rem`. Flex basis represents the 'ideal' width, and does not preclude the element from growing or shrinking under suitable circumstances.
```css
.not-sidebar {
min-width: 50%;
}
.sidebar {
flex-basis: 20rem;
}
```
If I give the container element `flex-wrap: wrap`, the sidebar's companion will be forced onto a new line as soon as the `50%` threshold is reached. It works just like the text wrapping algorithm but with HTML elements rather than words.
```css
.with-sidebar { /* the common parent element */
display: flex;
flex-wrap: wrap;
}
.not-sidebar {
min-width: 50%;
}
.sidebar {
flex-basis: 20rem;
}
```
Now we just need to ensure each element, the sidebar and the non-sidebar, grows to take up the available space. The sidebar takes `flex-grow: 1` (which essentially means 'yes please: grow if there's free space') and the non-sidebar takes an absurdly high `flex: 666` (most people choose `999` but I'm a satanist).
```css
.with-sidebar { /* the common parent element */
display: flex;
flex-wrap: wrap;
}
.sidebar {
flex-basis: 20rem;
flex-grow: 1;
}
.not-sidebar {
min-width: 50%;
flex-grow: 666;
}
```
The reason for this high value is to ensure the non-sidebar takes up all of the free space wherever the two elements are adjacent. The sidebar's `flex-basis` value is not counted as free space and is subtracted from that calculation.
Here's something that's nice: that `max-width: 50%` declaration? It refers to the parent element's width, _not_ the viewport width. This makes the behavior more like that of a so-called 'container query' than a traditional media query. Container queries are still being specified and so far haven't been adopted by browsers. Here, we've kind of mimicked the _behavior_ of a container query without using anything like a JavaScript polyfill.
What if we want a margin between our sidebar and non-sidebar? If we add a margin to the sidebar's right-hand side, we solve the problem for contexts where the two elements are adjacent. Things get weird and gross when the non-sidebar wraps...
The smart solution adds margin all around the two elements then—and this part id important—uses a negative margin on a common parent element to take the excess margin away. It's kind of like removing the excess pastry around a pie lid.
Now, margin will appear between the two elements in either configuration, but the sides will always be flush, and there will be no extra margin above or below the component.
If you want a gap of `1rem`, you need to add a margin of `0.5rem` to each of the elements, then remove `0.5rem` from the parent.
```css
.with-sidebar {
margin: -0.5rem;
}
.with-sidebar>* {
margin: 0.5rem;
}
```
The upshot is the component can take a sidebar of whatever width you like, and Flexbox will take care of the layout no matter the context. This `<with-sidebar>` custom element just needs the `width`, `margin`, and `side` properties, and any two child elements.
Inside the component, we can add the `not-sidebar` class to the appropriate child element, based on the value of the `side` prop. Since `this.children` is an array, `0` represents the first, or left, child and `1` the second or right one.
So what if we wanted to create an effortlessly responsive grid? The algorithms powering the CSS Grid module make this similarly easy. In Grid's case, all of the necessary properties are placed on the parent.
The `grid-template-columns` property sets out the grid into which child elements are positioned. The `repeat()` function means grid cells are created on-demand to accommodate any number of child elements. The `auto-fill` keyword tells cells to distribute themselves to take up the available space, wrapping where necessary, and `minmax` sets out the minimum and maximum width for any and every cell.
Grid gap adds gaps only between cells. It has the same effect as the negative margin technique discussed for the Flexbox sidebar component, but isn't a hack.
The resulting behavior is one of flexibility, but still order. No breakpoint interventions are necessary at any point along the spectrum of all viewport widths. It just works.