dabble in precision with css grid
-
Quick jump:
- 1. lines and areas
- 2. gaps
- 3. Track sizing with fr and minmax
- 4. auto track creation
- 5. justify and align items and tracks
- 6. repeat: auto-fill vs auto-fit
CSS grid is one of the newer additions to CSS. It is unique among CSS layout techniques as it places elements using 2d grid coordinates rather than the default document flow.
It splits the "design of the layout" and the "placement of elements" into two distinct steps during development, forcing the developer to design the grid top-down first and then place the elements into it (as opposed to placing the elements into the DOM then working out which styles to apply to get the desired layout).
Grid is like its own layout language inside of CSS. It seems complicated at first, but once you learn the principles it becomes a pliable tool for laying out your designs as you envision (especially responsive designs)
Grid differs from other CSS layout techniques (like normal flow and flex) in that they typically use the size of children to implicitly size the parent or push sibling elements into the right position. Non-grid methods cannot easily have white space or align things along both the X and Y axes. Flex does not have the fr unit, but it can distribute free space to items using flex-grow and flex-shrink. Grid uses fr to distribute free space to tracks which allows further per-item customization. See #grid-vs-flex for details.
display:grid is applied to a parent container, and then all the direct child elements become grid items. Grid items stretch to fill the cell area they are placed into, both width and height wise. If you have not assigned a grid cell area to a child grid item, they will be placed using an auto-placement algorithm (by default it places child elements one per cell left-to-right, and then repeats on the next row down). Grid also allows a auto-creation of rows and columns that are created based on the grid items (no need to statically define the exact number of grid rows and columns).
Can I Use: Grid
lists browser support at 98% - it's fine to use. But if
you are developing for older browsers you can progressively
enhance with
@supports (display: grid) { }.
Lines and areas ↑
Example 1 below has a DOM structure like this:
<div class="grid-container">
<div class="red"></div>
<div class="blue"></div>
</div>
-
Row
Rand ColumnClines are numbered from 1.- Lines are used for item placement (not the "tracks" which are the actual space of the row/col).
-
Elements are placed on the grid by putting them
inside an
area
that is defined by 4 lines:
- R-start, C-start, R-end, C-end.
-
Elements can overlap.
- DOM order determines stacking order - later elements drawn on top.
- Different CSS notations can be used to define the same grid-area.
Click two cells to place a element in that grid area:
- grid-area
-
E.g.
grid-area: 1 / 2 / 3 / 4 -
A single key that sets 4:
- grid-row-start, grid-row-end, grid-column-start, grid-column-end
-
grid-row
and
grid-column
also sets the above 4 keys using a
start / endformat.
-
Tips for remembering syntax and visualizing
areas.
- The syntax for grid-area can be confusing as it's just numbers delimited by a forward slash.
-
The format is
RCRC.-
Ris Row andCis Column. -
E.g.
-
grid-area: 1 / 2 / 3 / 4 - Should be read as:
-
--start----end--RCRCgrid-area:1/2/3/4
-
-
-
Remember that the numbers have implicit
types.
-
R1andC1are not interchangeable, but both would be1in CSS.
-
-
You can visualize the numbers as
pairs:
-
R1-startandR3-endare two row lines that are parallel; you are selecting the space in between. -
C2-startandC4-endthen does the same with two column lines, overlaid on the above row lines to create a rectangle shaped grid area for placing elements.
-
-
Values that can be used for lines:
-
span 4means "span 4 tracks" or "count 4 tracks" and allows you to define an area without a concrete end line number.- Useful when moving elements to another grid location.
- auto is the default and uses auto-placement for that line.
-
-1(negative one) is the last line.-
-2is the second from last line etc.
-
-
any-custom-line-name(lines can be given names and referenced).
-
Gaps ↑
- gap, row-gap, column-gap
-
Grid gaps apply to row and column lines that are
not the first or last lines.
- Only the middle lines, not the grid edges (lines 1 and -1 are the edges).
-
Gap
- Is split evenly either side of a line.
- Acts like padding on the grid track.
- Can only have one size for all of a given row/col.
-
Gaps are kind of like row or column tracks that you
cannot place items into.
- For some designs it may be better to use tracks instead of gaps so that you can place elements into them if needed in the future.
-
Valid gap units:
- Absolute units: px, cm, mm, in, pt, pc.
- Relative units: em, rem, vh, vw, vmin, vmax, %.
-
Note:
- fr does not work with gaps.
-
% is a percentage of the grid container
without gaps.
- row-gap: %-of-container-height is used.
- column-gap: %-of-container-width is used.
Click white two cells to place a cell, then adjust the gap sizes:
Sizing rows and columns (aka tracks) ↑
- Grid rows and columns are called "tracks".
- Elements placed inside a grid container are called "grid items". By default, items take the full width and height of the cell area they are placed into.
-
Rows and columns are defined with the
properties:
- grid-template-rows
- grid-template-columns
-
An example:
-
grid-template-cols: 50px 50px - This is a two column layout, each column is 50px wide.
-
-
Grid-specific units:
-
fr
- A fraction of left over space in the grid container.
-
minmax
- Size the track between this range.
-
min-content,
max-content
- min - squash. Wrap text to make it as narrow as possible.
- max - expand. Never wrap text. The track becomes as big as the longest line of text.
-
fit-content()
-
fit-content(100px)means min size is content, max size is 100px. -
The keyword
fit-content
is not used in grid tracks.
-
It is only for element
widths:
width: fit-content.
-
It is only for element
widths:
-
- auto
-
fr
fr ↑
-
fr
the "remaining space left in the container
after absolute values take their space", then
divides it among all
fr
values in the same
grid-template-xvalue. - This example shows the fr unit applied to grid columns (grid-template-columns), but it can also be applied to rows (grid-template-rows).
- Select a combination of fr and absolute px using the sliders to see how the column's are divided.
-
Columns with
fr
always expand to fill the remaining grid
container space
(but never over-fill it).
- Setting absolute px values for all cols will under-fill or over-fill the container (try it below).
-
Tracks do not always need to fit into their
grid container - they can be smaller or
larger.
- fr makes it easy to fit the tracks exactly into the container space.
-
fr
differs from percentage.
- Percentage only uses the grid containers size.
- fr is a fraction of free space (taking into account the space already used by other grid tracks).
- Click the white cells to place a grid item in that grid area - see how the item expands and contracts with the columns.
- If you are on a desktop: resize your window to make it very narrow (resizes the grid container). Watch the fr values recalculate.
minmax ↑
- minmax is a tool to distribute space to tracks in a grid container.
-
minmax
provides the ability to:
- Use a px min with a fr max.
- Use px values for both min and max (fr-like space distribution but with static px values).
- Only used in grid-template-columns or grid-template-rows.
-
minmax
sets a track (row or col) to be within the range
min >= track_size <= max. -
This example uses
minmax = mmfor brevity. -
There are two types of
minmax
definition:
-
A. Static values only:
mm(25px, 100px). -
B. Uses
fr
as a max arg:
mm(25px, 1fr).
-
A. Static values only:
-
How
minmax
distributes space:
- 1. All cols start at their min.
- 2. As the container grows, space is given to only type A (static) track types until they all reach their max.
-
3. Then type B's will have space added
in the correct fr ratios.
- The fr applies to the whole track size (includes the space already taken by min).
-
When using minmax with fr, the
fr ratio may not be correct to
start with.
-
As an example:
-
mm(25px, 1fr) mm(25px, 10fr)- The A:B ratio between the mins is 1:1, but the ratio between the frs is 1:10.
- When the container grows space is added to col B first to try to "correct" the fr ratios.
-
The sizing
steps as the
grid
container
grows would
be:
-
1.
25px : 25px(min values set). -
2.
25px : 250px(1:10 ratio reached). -
3.
26px : 260px(1:10 ratio maintained).
-
1.
-
-
As an example:
- Related: Official track sizing spec
- A fr is not valid for a min value.
-
When visualizing a set of tracks defined with
minmax, consider what your design looks like at these
four steps:
-
1. Minimum widths all set.
- What do the tracks look like when all the minimums are set?
-
2. Static maximum widths all
reached.
- What do the tracks look like when all the static maximums are reached?
- Note: All fr columns are still at their minimums at this step.
-
3. Optional: fr column ratios are being
balanced.
- What do the tracks look like when the fr ratios are not yet balanced?
- This is the most complicated step, and it may be easier just to ignore it and instead envision the jump between step 2 and step 4.
- Minimum values will cause the fr ratios to be incorrect initially.
- Space is assigned to the column with the smallest px-per-fr first (calculated by taking the current px width of the track and dividing it by its fr).
-
4. fr column ratios maintained.
- All fr tracks are in the correct fr ratios, all static maximums are reached.
-
1. Minimum widths all set.
- The example below shows you each of these steps.
- Change the grid container width and select different track configs - try to predict the track sizing before resizing the container. You can also add your own via the text box. Bookmark this as the minmax simulator to test your future designs.
Auto track creation and sizing ↑
- Three CSS properties work together to auto create tracks:
-
Tracks are auto created in 3 cases:
- 1. When grid auto-places items.
- 2. When you place an item beyond the explicitly defined grid.
- 3. When grid-template-areas gives names to tracks beyond the explicitly defined grid.
- Note: the explicit grid tracks are defined with:
- When grid auto-places items, it only creates tracks for the direction defined in the grid-auto-flow.
-
The size of auto-created tracks.
-
grid-auto-columns: 50px- All new columns are 50px.
-
grid-auto-columns: 50px 100px- All new columns alternate between 50px and 100px.
- auto is the default size for auto-created-tracks.
-
-
Note
-
Negative line numbers
never include the implicit auto
tracks.
- -1 is always the last explicit track, even if there are new auto tracks afterwards.
- Positive line numbers behave as expected (they include auto tracks).
-
Negative line numbers
never include the implicit auto
tracks.
-
Change "items" to set the total grid
items.
- All items have no grid-area set so will be auto-placed, auto-creating tracks if there is no space in the explicit grid.
-
Item colors:
-
Blue
- Explicit grid cell found.
-
Green
- Explicit grid cell not found, auto-placed in a created auto-track.
-
Blue
Justify and Align ↑
-
justifyandalignmanage white space. -
justifyis for the x-axis (horizontal) -
alignis for the y-axis (vertical). -
There are two "types" of things that
justifyandalignapply to:-
1. Grid items.
- justify-items, align-items (set on the grid container)
- justify-self, align-self (set on the grid item)
- The grid item is squashed (along one axis) to be the same size of the content it contains, then it is aligned within the grid track.
-
Default:
stretch,
stretch
- Take the full space of the grid cell (width and height), leave no white space.
-
2. Grid tracks.
- justify-content, align-content (set on the grid container)
-
Only used when the tracks do not
cover the entire grid
container.
- This unused space can then be distributed.
-
Default:
start,
start
- Start the tracks in the top left corner of the grid container.
- If the total size of the tracks does not cover the grid container, leave the remaining space as white space.
-
space-around,
space-between,
space-evenly
- These add space to the outer most edges of the start and end tracks, and between the tracks (it adds the space to the gap).
- Other values add all of the space to the outer most edges (e.g. "end" adds all extra white space to the top edge to push the tracks against the end of the grid container).
-
1. Grid items.
- Items can have these values:
-
Tracks can have these values:
- normal
- start, end
-
stretch
- This gives the white space to the tracks that are auto.
-
space-between
- No space at the edges.
- Add all spaces to gaps between tracks.
-
space-around
- A single track has equal space added both sides (including the edges).
- Results in the total space between two tracks being 2x that of the space at the edges.
-
space-evenly
- Extra space is given equally to every gap including the outer most edges.
- Gap size between two tracks is the same as the space given to the edge.
- baseline, first baseline, last baseline
Test out the different justify and align values. Change
the size of the grid container and set the
-content
values to
space-x. Note that the space between the tracks behaves
similarly as gap (it is added to the existing gap if it
is set). Also note the space can be added to the edges
of tracks (unlike gap).
repeat: auto-fill vs auto-fit ↑
-
repeat
is a function that can be used in
grid-template-columns.
-
E.g.
-
grid-template-columns: repeat(2, 60px); -
grid-template-columns: 60px 60px - Both of these are the same (two 60px tracks).
-
-
E.g.
-
There are two special keywords that can be used in
place of a number:
-
1.
auto-fill
- Create as many tracks as possible (by using the min track size from the track definition).
- Ignore any items.
- Keep empty tracks.
-
2.
auto-fit
- Create as many tracks as possible (same as above).
- Then: if there are less items than tracks, remove the empty tracks and stretch the remaining tracks (up to the per-track max) to cover the grid container.
-
How
repeat
differs from auto-tracks (grid-auto-rows).
- Auto-tracks can only be generated for one axis at a time (either rows or columns).
-
repeat
with
auto-fill
or
auto-fit
are used to create the explicit
grid.
-
There are distinct lower
and upper bounds on the
number of
repeat
tracks based on the min/max
values of the track
definition and the grid
container size (the tracks
must fit into the grid
container).
- Initial grid container size determines how repeat sizes tracks.
-
There are no upper bounds
on the amount of auto-tracks
generated - the more items
you place in the grid the
more new auto-tracks are
created (e.g lots of new
rows). As more items are
added, new auto-tracks are
created which then expands
the grid container.
- Items overflowing the explicit grid cells trigger new auto-tracks.
-
There are distinct lower
and upper bounds on the
number of
repeat
tracks based on the min/max
values of the track
definition and the grid
container size (the tracks
must fit into the grid
container).
-
1.
auto-fill
Change the item count so that the first row is partially empty, then toggle auto-fill and auto-fit. Notice the tracks are stretched in auto-fit.
Grid vs Flex ↑
-
Flex
- Single row or single column of items.
- When you want to align items to the sides or center of the container.
-
Items size themselves.
- A missing item does not leave a gap.
-
Grid
-
When you want to distribute space to
tracks.
- Given a container width or height, you want to divide it into sections using minmax or auto tracks.
- You want large areas of white space in the design.
- You want the items to take the exact size of the tracks, both width and height.
- Align items in two dimensions.
- Removing an item does not effect the other items in the grid (when not using auto placement).
- When you want to dabble in precision.
-
When you want to distribute space to
tracks.
-
Similarities.
-
fr
vs flex-
-
Grid uses
fr
to distribute the free space to
tracks. Items are then placed
into those tracks.
-
This isolates the
distribution of free space
from the item.
- This enables further per-item changes after the free space has been distributed to tracks (you can manipulate the item inside of the track without affecting the track).
- Flex in contrast applies the free space directly to the items.
- With fr free space can be distributed in two dimensions (a single cell can have free space distributed to both its axes based on the row and column track definitions).
-
This isolates the
distribution of free space
from the item.
-
Flex has
flex-grow
flex-shrink
and
flex-basis
-
Shorthand:
flex: 1 0 200px - flex-grow sets the rate of relative growth to other items.
- flex-shrink sets the rate of relative shrinkage to other items.
- flex-basis defaults to auto meaning "the size of content". When it is 0, it means "0px" starting size (not a rate of change like grow or shrink).
-
Shorthand:
-
Grid uses
fr
to distribute the free space to
tracks. Items are then placed
into those tracks.
-
fr
vs flex-