- INDEX
Layouts are the way we arrange elements on a page.

-
We usually have general layout for the entire page, and then we have specific layouts for each (section / component) of the page.

-
Fixed width vs Liquid Layouts
-
- Here, the design doesn't change the size when the viewport changes (like when the user resizes the browser window)
-
Liquid layout:
-
Here, the design stretches and contracts as the viewport changes.
-
This is called a responsive design (more here)
-
designs stretch and contract as the user increases or decreases the size of their browser window. They tend to use percentages.

-
-
Flow layout is the default layout mode. A plain HTML document, with no CSS applied, uses Flow layout exclusively.
In Flow layout, every element will use a display value of either inline, block, or inline-block. This value governs how the Flow layout algorithm will place the element. The default value depends on the tag; div elements are block by default, while spans are inline.

-
- They can be used to create a block of text, or to arrange boxes into a layout.
- They can have
margins,padding, andbordersfor all directions (top, right, bottom, left) and they respectwidth/heightproperties.
-
-
They are generally meant to highlight a selection of text.
-
They can have
margins,padding, andbordersonly for (right/left) and doesn't respecttop/bottommargin & padding, and they also don't respectwidth/heightRemember from the visual formatting model that CSS has a block direction (vertical) and an inline direction (horizontal). Inline elements are laid out in the inline direction, so they don't have a width or height. They only have a width and height if they're converted to block-level elements.
- To make them respect
width/height-> usedisplay: inline-block;
- To make them respect
-
They respect space between them in the HTML file, so if you have a space between them in the HTML file, it'll be shown in the browser.

-
-
Inline-block elements:
- It's an element that internally acts like a block element, but externally acts like an inline element. The parent container will treat it as an inline element, since it's external. But the element itself can be styled like a block.
- it's a mix between
blockandinlineelements - it looks like an
inlineelement but behaves like ablockelement
- it's a mix between
- can have
margins,padding, andborders✅ - it doesn't line-wrap as
inlineelements do ❌
- Note:
- It's an element that internally acts like a block element, but externally acts like an inline element. The parent container will treat it as an inline element, since it's external. But the element itself can be styled like a block.
It's a CSS property that allows an element to be pushed to the left or right (removed from the normal document flow), and the other elements will wrap around it.
-
float:left=> means tha the element will be on the left and the elements after it will flow around it from its right
-
floatis sometimes used to create Multi-Column Layouts.column1of3, .column2of3, .column3of3 { width: 300px; float: left; /* they will be floated to the left one after the other */ margin: 10px; }
-
When element is floating it acts like it's not in the page like
position:absolute, this means that if the element next to it haspadding=> thepaddingwill override the floating element and not start at its end.- To fix this, we can also make the next element
floattoo or useclear:bothon the next element
- To fix this, we can also make the next element
Floats have one notorious drawback—if you're not careful, they can break your layout. For example: Watch what happens when an image is floated without much content beside it: (This is called a "float drop" or "Collapsed Height")
<style>
.floated {
--breathing-room: 16px;
float: left;
shape-outside: url(/course-materials/me-light.png);
margin-right: var(--breathing-room);
shape-margin: var(--breathing-room);
width: 125px;
}
/* Cosmetic styles */
.wrapper {
max-width: 600px;
padding: 32px;
margin: 0 auto;
background: white;
border-radius: 8px;
}
body {
padding: 16px;
}
</style>
<div class="wrapper">
<p>
<img class="floated" src=3d-avatar.png" alt="3D avatar" /> Lorem Ipsum is simply dummy text.
</p>
</div>-
When we float an image, we take it out of flow. When the parent
.wrapperis trying to determine how tall it should be, it ignores floated elements just like it'd ignore an absolutely-positioned one. -
Collapsed Height:
- If a parent element only contains floated elements, some browsers may render it as zero pixels tall, effectively making it invisible if it doesn't have a noticeable background.

- To fix this, we can:
- use
clear:bothon the parent element -> Clearfixing - use
overflow: autoon the parent element
- use
- If a parent element only contains floated elements, some browsers may render it as zero pixels tall, effectively making it invisible if it doesn't have a noticeable background.
The clear property allows us to place additional content below a floated element, in case we don't want it to wrap around it:
-
The
clearproperty allows you to say that no element (within the same containing element) should touch the left or right-hand or both sides of a box. -
clearhas four valid values (it's like to ignore any floated item from specified direction): -
we use
clearproperty when we want the surrounding element to not be floated around element with afloatproperty -
Example:
<style> .clearfix::after { content: ''; disaplay: block; clear: both; } </style> <div class="wrapper clearfix"> <img class="floated" src="/course-materials/me-light.png" alt="3D avatar" /> <p>Lorem Ipsum is simply dummy text.</p> </div>
- Our parent
.wrapperelement now renders a pseudoelement that appliesclear: both(which will clear both left and right floated elements) right after the content. It doesn't actually matter that this element is empty; the fact that it exists causes the parent to grow to include the entire floated element, and the0px-tall element below.
- Our parent
-
Here's a generic
clearfixclass:.clearfix::after, .clearfix::before { content: ''; clear: both; display: table; } // or if you're using sass, you can make it a mixin @mixin clearfix { &::after, &::before { content: ''; clear: both; display: table; } } .container { @include clearfix; }
-
There's a new way to clear float -->
display: flow-root
-
Historically, a floated element would "block out" a rectangle. Text would wrap around that rectangle. Recently, floats have gained an additional superpower: they can now specify a shape for text to wrap around! This is done with the
shape-outsideproperty. -
shape-outsidelets us specify a shape that text should wrap around. circle is the most straightforward value, but it accepts many different shapes: -
Example
<style> .floated { float: left; shape-outside: circle(); margin-right: 24px; /* Cosmetic tweaks: */ width: 125px; border-radius: 50%; } </style> <div> <p> <img class="floated" src="/course-materials/cat-avatar-250px.jpg" alt="Yawning kitten" /> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. </p> </div>
shape-outsideis a hidden gem. Most developers assume that floats aren't relevant anymore, and they miss out on some pretty cool functionality as a result! And because this effect is so rarely used, it really stands out to users.
Positioning is the process of determining the location of an element on the page.
- The difference between it and
margin(when moving an element) is thatmarginwill move the element but it will still take up the space in the normal flow, whilepositionwill move the element and remove it from the normal flow.
In CSS, the position property is used to control the layout of an element. It has 5 possible values: (static, relative, absolute, fixed, sticky)

-
static- It's the default value
- It means that the element is positioned according to the normal flow of the document.
- Here,
top,right,bottom, andleftproperties have no effect.
-
relative -
absolute-
It makes the position of the element to be relative to nearest parent element with
relativepositioning (its container) until we reach the<body>element

-
It removes the element from the normal flow of the document, so it doesn't take up space in the normal flow.
- When the browser is laying out elements, it effectively pretends that absolutely-positioned elements don't exist. They're “incorporeal”: you can stick your hand right through them, like a hologram or a ghost.
- Being able to take elements out-of-flow is super handy. Any time you want an element to be "floating above" the content, like a tooltip or a dropdown or a modal, absolute positioning is your friend.
- It might cause the parent container to collapse (if all its children are absolutely positioned)
-
it can also be used to center an element horizontally and vertically
.box { position: absolute; top: 0; left: 0; right: 0; bottom: 0; width: 200px; height: 200px; margin: auto; }
- This works because
top: 0; left: 0; right: 0; bottom: 0;will stretch the element to fill the entire parent container, andmargin: auto;will try to add equal margins on all sides, which will center the element.
- This works because
-
How absolute positioning works:
- When deciding where to place an absolutely-positioned element, it crawls up through the tree, looking for a Positioned ancestor. The first one it finds will provide the containing block. If it doesn't find one, it will use the
<html>element as the containing block. - The containing block is the area in which the absolutely positioned element is positioned. It's like a little window into the world of the document. The absolutely positioned element is positioned within that window.

- The absoluted positioned element ignores the
paddingof the parent element, it sits right up against the edge (border) of the parent element (becausepaddingis used in the normal flow calculations, and the absolutely positioned element is removed from the normal flow)
- When deciding where to place an absolutely-positioned element, it crawls up through the tree, looking for a Positioned ancestor. The first one it finds will provide the containing block. If it doesn't find one, it will use the
-
Normal vs Absolute positioning:

- positioned elements will always render on top of non-positioned ones.
- What if we set both elements to use relative positioning? In that case, the DOM order wins.
-
-
fixed- Here, element is removed from the normal flow and positioned relative to the root container element (viewport). (no space is reserved for it in the normal flow)

- The main advantage of fixed-position elements is that they're immune to scrolling.
- When you scroll the page, the element stays in the same place (because it's fixed/relative to the viewport)
- Here, element is removed from the normal flow and positioned relative to the root container element (viewport). (no space is reserved for it in the normal flow)
-
sticky-
It toggles between
relativeandfixedonce thepositionvalue is met in the viewport, then it sticks.nav { position: sticky; top: 0; /* once it reaches the top=0 with the viewport, then it will stick */ }
-
In addition, you also need to pick at least one edge to stick to (
top,left,right,bottom). Most commonly, this is done withtop: 0px.
-
It's used for sticky navigation bars (when you want the navigation bar to stick to the top of the page when you scroll down)
-
It differs from
fixedin that: -
Usually used for sticky headers or sticky sidebars or sticky table headers
-
-
Notes:
-
when using
absoluteposition withinset: 0, it makes the element expand to fill the height and width of the closest parent with a non-static position- inset: The inset property in CSS is a shorthand for the four inset properties,
top,right,bottomandleftin one declaration. Just like the four individual properties themselves, inset has no effect on non-positioned (static) elements. In other words, an element must declare an explicit position value before inset properties can take effect.
- inset: The inset property in CSS is a shorthand for the four inset properties,
-
A common problem when using
stickyis that: "There's a thin gap above my sticky header!"-
If you intend for an element to sit right against the edge of the viewport, you might discover a thin
1pxgap between the element and the edge in Chrome. We can fix this by addingtop: -1to the sticky element..nav { position: sticky; top: -1px; /* -1px instead of 0px */ }
-
-
It specifies the elevation of an element relative to other elements on the page.
-
stacking context -->
z-index:-
It's automatically created for each element when it has a position value other than
static(likerelative,absolute,fixed,sticky) -
It's as if the blocks have been stacked on top of each other on the Z axis

Note: All the child elements of the parent element will be in the same stacking context as the parent element. meaning that even if the child element has a
z-indexvalue, it will be compared to the parent element'sz-indexvalue. and not to the other elements on the page. (this might cause some issues for modals and dropdowns) -
-
by default, it's equal to
autowhich is equal to0. -
if multiple elements have the same
z-index, then the last one is higher than the others and so on.
-
Notes:
-
you can't hover on something that have a negative
z-index -
There's a CSS property called
isolationthat can be used to create a new stacking context for an element, which can be useful when you want to prevent an element from being affected by thez-indexof its parent element..parent { isolation: isolate; }
-
-
Notes:
⚠️ z-indexonly works on positioned elements (elements with apositionvalue other thanstatic)- the Flexbox algorithm also supports z-index. If our element is being laid out with Flexbox, it uses z-index as if it was rendered with Positioned layout.
- The same thing is true for CSS Grid; a child in Grid layout can use z-index without setting position: relative.
It is a layout method for laying out (distributing) items in a single dimension, either as a row or a column.

-
It allows us to distribute space dynamically across elements of an unknown size, hence the term "flex".
-
- Flex Container: The parent element that contains the flex items.
- Flex Items: The children of the flex container.
- Main Axis: The primary axis along which the flex items are laid out.
- Cross Axis: The axis perpendicular to the main axis.
-
List of all the properties that can be used on the flex container & flex items:

Good reference -> Flexbox30
You can use the flex-direction property to specify the direction in which the flex items are displayed.
-
flex-direction: row;=> default -
flex-direction: column; -
flex-direction: column-reverse;-> means that the items are laid out vertically, from bottom-to-top
-
flex-direction: row-reverse;-> useful when you want to align the items from left to right, which is needed for some languages like Arabic-
If we want to flip the order of children without changing their alignment, we can do so with justify-content:
.flex-container { display: flex; flex-direction: row-reverse; justify-content: flex-end; }
-
Note: Visual order only!
When we change the order of flex children using
row-reverseorcolumn-reverse, it only affects the visual presentation. Keyboard and screen reader users will still navigate items in the original DOM order. This can be beneficial, but be mindful not to inadvertently worsen accessibility.
-
justify-content -
align-items- It aligns the items inside a flex container along the cross axis.
flex-direction: row=> aligns the items vertically
baseline-> aligns the items to the baseline of the container which is the line where the text sits

- If you want to center nav items in a navbar, but you want the items words to be aligned to baseline, you can wrap the items in a
divoruland applyalign-items: centerto the flex container andalign-items: baselineto thedivorulthat wraps the items.
flex-direction: column=> aligns the items horizontally
- default value ->
align-items: stretch;=> stretch the items to fill the container (if the items have a height, then it will be ignored) - when to use
align-items: baseline;?- usually in Navbar, where we have a logo and you want the navbar links to be aligned with the logo
- Trick: When working with navbars, you can use:
align-items: baseline;to align the items to the baseline of the container (usually the logo and the nav links) -> on desktop sizealign-items: center;to center the items (logo & icons) vertically -> on mobile size
- It aligns the items inside a flex container along the cross axis.
-
align-content-
It aligns the lines of items along the cross axis (when there are multiple lines of flex items)

-
It has no effect when there is only one line of flex items. So use it when you have multiple rows/columns in your flex-container
-
So the flex items need to be wrapped in order to see the effect of
align-content.flex-container { display: flex; flex-wrap: wrap; /* Required: wrap the items to have multiple lines */ align-content: space-between; }
-
-
-
align-self- It allows the default alignment (or the one specified by align-items) to be overridden for individual flex items.

auto=> defaultstretch=> stretch the items to fill the container (if the items have a height, then it will be ignored)center=> center the items verticallybaseline=> align the items to the baseline of the container (usually used in Navbar)- Ex: align the first nav item to the right
- Notice here that by using
align-self: center;on an item, it's instead of centering all the items, it centers only the item that has thealign-selfproperty, so it's a replacement foralign-itemsbut for a single item
- Notice here that by using
⚠️ Note: we don't havejustify-selfin flexbox, because it's not needed. We can useflex-grow,flex-shrink, andflex-basisto control the alignment of the items along the main axis. - It allows the default alignment (or the one specified by align-items) to be overridden for individual flex items.
-
Content vs Items:
align-contentis used to align the lines of items along the cross-axis (when there are multiple lines of flex items)align-itemsis used to align the items inside a flex container along the cross-axis.
It defines whether the flex items are forced in a single line (default) or can be flowed into multiple lines (wrapped into new line). If set to multiple lines (when there's not enough space & overflow happens), it also defines the cross-axis which determines the direction new lines are stacked in.
The
cross axisis the axis perpendicular to the main axis.
Note: the wrapping happens when the item shrinks to its (width/basis) and not the minimum-content-size of the item (which is the handled by flex-shrink)
nowrap(default)wrap- multi-lines, direction is defined by
flex-direction - It means that when the end of line is reached, make the items keep their
width/heightand go to the next line- if
flex-direction: row=> the items will go to next row vertically - if
flex-direction: column=> the items will go to next column horizontally
- if
- multi-lines, direction is defined by
wrap-reverse
By default, all flex-items have order: 0, and are laid out in the order they appear in the HTML markup. You can use the order property to change this ordering.
.item {
order: 0; /* default */
order: 1; /* move the item to the end */
order: -1; /* move the item to the beginning */
}-
It works like
z-indexbut in the main axis (a child withorder: 2will show up after a child withorder: 1but before a child withorder: 5) -
Why do we need to use
order?-
It is useful when you want to change the order of the items in the source code, but you don't want to change the HTML structure
-
Accessability: with screen-readers, it is important to have the correct order in the source code so that the screen-reader can read the content in the correct order, So we can set the items order in the source code as we want the screen-reader to read it, and then use
orderto change the order of the items visually -
Example:
-
if you have a table of contents in a blog post, you might want to have the table of contents at the start (left) of the post, but you want it to appear at the end (right) of the post visually, so you can use
orderto change the order of the items visually
-
Solution:
<style> .container { display: flex; flex-direction: row-reverse; } </style> <div class="container"> <div class="toc">Table of Contents</div> <div class="content">Main Content</div> </div>
-
Another solution abviously is to change the
tabindexof the items in the source code, but it's not recommended because it's not a good practice to change thetabindexof the items
-
-
In Flexbox, width and height properties are not hard rules (mostly ignored), they are just suggestions (and it will be changed for some situations). The flex property is a shorthand property that sets the flex-grow, flex-shrink, and flex-basis properties.
-
flex-grow-
Determines how much of the available space inside the flex container the item should take up.
.item { flex-grow: 0; /* default -> item is not allowed to grow */ flex-grow: 1; /* item is allowed to take up all the extra available space */ flex-grow: 2; /* item should take twice as much space as the other flex elements */ }
-
It represents the item's share of the container's empty space, not the item's own size. (relative to the other flex items in the container)

-
It won't have any effect if there's no extra space in the container (if the container is full)
-
-
flex-shrink-
it determines how much the flex item will shrink relative to the rest of the flex items in the flex container (when there isn't enough space on the row/column).
.container { display: flex; width: 400px; } .item { width: 200px; /* we have 3 items, so the total width is 600px (biggest than the container width) */ } .item { flex-shrink: 0; /* item is not allowed to shrink */ flex-shrink: 1; /* default -> item is allowed to shrink */ flex-shrink: 2; /* item is allowed to shrink twice (faster) as much as the other flex elements */ }
-
Notes
- It won't have any effect if there's enough space in the container (the container has extra space)
- the shrink value won't matter when we reach the minimum width of the item-content, as the item can't shrink anymore.
- Whenever you need to have an element takes
1/3or1/4of the space, you can:- Option 1: use
flex-grow: 1for all the items andflex-basis: 0for the item you want to take1/3or1/4of the space - Option 2: use
flex: 1for the item you want to take1/3or1/4of the space andflex: 2for the other items (if you have 2 items)
- Option 1: use
-
-
flex-basis-
It sets the initial main size of a flex item unless
width/heightis set first.
- It acts like
widthfor flex-items if the direction isroworheightif the direction iscolumn(it's agnostic to the main axis direction)
- It acts like
-
use it instead of
widthfor flex-items if the direction isroworheightif the direction iscolumn.flex-item { flex-basis: auto; /* default -> based on the width/height of the content */ flex-basis: 100px; /* fixed size */ flex-basis: 50%; /* percentage */ }
-
it's recommended to ues
percentages %and notpixelunits forflex-basisto make the layout responsive -
it doesn't work ❌ if:
flex-growis set to0flex-shrinkis set to0
-
It wins over
widthandheightproperties if they are set together.item { width: 200px; flex-basis: 100px; /* the item will have a width of 100px ✅ */ }
-
Trick: How to control number of flex items in the row of the flex container:
/* Flex Container */ .cards-container { display: flex; flex-wrap: wrap; justify-content: space-between; } /* 2 Flex Items */ .card { flex: 0 0 calc(50% - 2rem); /* the 2rem for the gap between flex items */ } /* 3 Flex Items (in a @media query) */ .card { flex: 0 0 calc(33.33% - 2rem); /* the 2rem for the gap between flex items */ }
-
Notes:
-
Important Gotcha: Always watch out when using the
flexshorthand property withwidthorheightproperties, as theflexproperty will override thewidthorheightproperties. (because it hasflex-basisin it which overrides thewidth/heightproperties)/* This item will have a width of 0px */ .item { width: 200px; flex: 1; /* means flex: 1 1 0; -> so the flex-basis will be 0 and the width will be ignored */ }
-
-
-
flexshorthand property-
It is a shorthand property used to specify the components of a flexible length (
flex-grow,flex-shrinkandflex-basis) in a short form..item { /* flex-grow: 1; flex-shrink: 1; flex-basis: 0%; */ flex: 1, 1, 0%; }
-
If used with only one value, it will be applied to
flex-growand the other values will be set to their default values (flex-shrink: 1; flex-basis: 0%).item { flex: 1; }
-
-
Takeaways
- There are two important sizes when dealing with Flexbox: Minimum content size (smallest without overflow) and hypothetical size (suggested size).
- Width/Height in Flexbox: Sets hypothetical size, not guaranteed.
flex-basis: Acts like width/height but takes priority.flex-grow: Expands to fill excess space.flex-shrink: Reduces size if container is too small, but not below minimum content size.
It's a new feature in CSS that allows you to add space between flex items in a flex container.
.flex-container {
display: flex;
gap: 5px;
/* or */
gap: 5px 3px;
/* or */
column-gap: 5px;
row-gap: 3px;
}
/* Old way (useful if there's no browser support) */
.flex-item {
margin: 5px;
}- usually
margin-right: autois used with the last flex item to push it to the right side of the flex container (usually in navbar) - flex containers act as a Block element, so note this when you apply
display: flexto a small item in order to center its contents display: flexvsdisplay: inline-flex- The difference between
display: flexanddisplay: inline-flexis that the former will make the flex container a block-level element, while the latter will make it an inline-level element.
- The difference between
flex-startvsleft:flex-startis used to align the items to the start of the main axisleftis used to align the items to the left side of the container.
It's a new layout system in CSS that allows you to create a grid of columns and rows to place content into. It's a two-dimensional layout system, meaning that it can lay out items in rows and columns simultaneously.
Ultimate Guide to css grid ->
It consists of a Grid container and Grid items (Cells)

-
Grid lines: These are horizontal and vertical lines dividing the grid into rows and columns. The numbers represent lines.

- Every row needs to have the same number of columns (and vice-versa). We can't have a grid where the first row has 1 column, the second row has 2 columns. But how is this not possible as most of the websites have different number of columns in each row?
- The answer is that this is done by combining multiple cells into one cell using
grid-template-areasproperty orgrid-columnandgrid-rowproperties.
- The answer is that this is done by combining multiple cells into one cell using
- CSS Grid is fundamentally different from the DOM, because the structure happens exclusively in CSS. There are no DOM nodes that represent the rows or columns in CSS Grid. Instead, the rows and columns are invisible markers, tools that our HTML elements can use to position themselves.
- Rows and columns are like the lines painted on the ground in parking lots. Drivers can use these lines to align their vehicles, but really they're just symbols. It's up to the driver to decide how to use them.
- Every row needs to have the same number of columns (and vice-versa). We can't have a grid where the first row has 1 column, the second row has 2 columns. But how is this not possible as most of the websites have different number of columns in each row?
-
Grid cells: These are the spaces between the grid lines. They are the smallest unit of the grid that can hold an item. The gaps between the cells are called gutters.
- They must be symmetrical (same size) in the grid, as css grid doesn't support zig-zag rows/columns. Every cell in the same row/column needs to have the same height/width.

- A grid-child can choose to span multiple rows and columns, but it must always produce a rectangle. No tetrominoes allowed like this:

- They must be symmetrical (same size) in the grid, as css grid doesn't support zig-zag rows/columns. Every cell in the same row/column needs to have the same height/width.
-
Old Grid System (960 pixel grid)
-
Before CSS Grid, web developers used a grid system like the 960 grid system to create layouts. It's a layout system that divides the page into 12 or 16 columns.

-
Each column has a width of
60 pixels, with a10 pixelmargin on each side. -
Each column has a margin set to 10 pixels, which creates a a gap of 20 pixels between each column and 10 pixels to the left and right-hand sides of the page.
-
Many CSS frameworks like Bootstrap and Foundation are based on this grid system, they provide a set of classes that you can use to create layouts.
-
-
In CSS Grid, there's no such thing as a "primary axis" or a "cross axis". The concept doesn't exist.
-
Instead, CSS Grid has rows and columns. The rows are always arranged along the "block" axis. In English and other horizontal languages, this is the vertical axis. Rows are always stacked one on top of the other. Columns are always arranged along the "inline" axis (horizontally).
-
When we change
grid-auto-flowfromrowtocolumn, we're not fundamentally changing the orientation of our grid; everything stays the same, except for the fact that our grid will have multiple columns instead of multiple rows.

.container { display: grid; grid-auto-flow: column; /* Now the remaining items will be placed in new columns */ }
-
-
Grid vs Flexbox
- Flexbox is a one-dimensional layout system, meaning that it can lay out items in rows or columns, but not both at the same time -> (Row or Column)
- Grid is a two-dimensional layout system, meaning that it can lay out items in rows and columns simultaneously -> (Row and Column)
-
Grid Construction
-
It consists of two main parts:
- Grid container: The parent element that contains the grid items.
- Grid items: The children of the grid container.
-
display: grid;=> creates a grid container, this container will be ablock-level elementdisplay: inline-grid;=> creates a grid container, this container will be aninline-level element
-
grid-template-columns- defines the columns of the grid
- defines the individual widths of each column
-
grid-template-rows=> defines the rows of the grid- It's common to only define the columns and let the rows be created implicitly
-
grid-template-areas=> setup the layout of the grid in a(visually-friendly way) by referencing the names of the grid areas which are specified with thegrid-areaproperty
-
It requires defining the (alias / name) of the cells in the grid, then assign the name to each element according to where you want it to be shown on the grid
.header { grid-area: header; } .sidebar { grid-area: sidebar; } .main { grid-area: main; } .footer { grid-area: footer; }
-
⚠️ Note: before usinggrid-template-area, you need to define the rows and columns of the grid usinggrid-template-columnsandgrid-template-rows
-
-
grid-template=> shorthand property that defines both the columns and the rows of the grid.container { display: grid; grid-template-rows: 200px 200px 200px; grid-template-columns: 100px 100px 100px; /* ---------------------- OR ---------------------- */ /* grid-template-rows / grid-template-columns values */ grid-template: 200px 200px 200px / 100px 100px 100px; }
-
When you have more rows than explicitly defined in the
grid-template-rows, the grid will create implicit rows to accommodate the content. but they will have a height ofauto(the height of the content inside them)-
To control the height of the implicit rows, you can use the
grid-auto-rowsproperty.container { display: grid; grid-template-rows: 200px 200px; /* the height of the explicit rows */ grid-auto-rows: 100px; /* the height of the implicit rows */ }
-
Same is applied for the columns using
grid-auto-columns
-
-
Aligning the grid itself in the container (to the grid structure, changing the columns/rows)
-
Aligning grid items in the tracks (to child elements, without affecting the grid structure)
justify-items=> aligns the grid items along the row axis (aligning columns)
align-items=> aligns the grid items along the column axis
place-items=> shorthand forjustify-itemsandalign-items
-
Notes:
-
Difference between
justify-contentandjustify-items: -
Note that the
-contentalignment only works when there's extra space in the grid container, while the-itemsalignment works all the time.- if the grid container is smaller than the content, the
-contentalignment will have no effect, but the-itemsalignment will still work.
- if the grid container is smaller than the content, the
-
-
gapis a shorthand forrow-gapandcolumn-gap -
It was called
grid-gapbefore, but it was changed togapin the new version of CSS Grid -
We can also use
row-gapandcolumn-gapseparately.container { display: grid; gap: 16px; /* or */ row-gap: 16px; column-gap: 16px; }
- By default, a grid-item will take up one grid cell in the grid container following the source order in the HTML markup.
- You can use different properties to position the grid items in the grid container.
It's used to position the grid items using values to specify which grid lines the item should start and end on.

-
In order to manually place the grid items in the grid container, you can use the following properties that specify the grid lines that the grid item should start and end on:
.item { grid-column-start: 1; /* Specifies on which column-line to start the grid item */ grid-column-end: 3; /* Specifies on which column-line to end the grid item */ grid-row-start: 1; /* Specifies on which row-line to start the grid item */ grid-row-end: 3; /* Specifies on which row-line to end the grid item */ /* or using shorthand properties ✅ */ grid-column: 1/3; /* start on column 1 and end on start of column 3 */ grid-row: 1/3; /* or using `span` */ grid-column: 2 / span 2; /* start on column 2 and span 2 columns */ grid-row: 1 / span 2; /* start on row 1 and span 2 rows */ grid-row: 2; /* (ONE VALUE) start on row 2 and end on the last row */ /* or using `-1` */ grid-column: 1 / -1; /* start on column 1 and end on the last column */ grid-row: -3/ -1; /* start on the 3rd row from the end and end on the last row */ }
grid-column=> shorthand forgrid-column-startandgrid-column-endgrid-row=> shorthand forgrid-row-startandgrid-row-end
-
spankeyword is used to specify the number of columns/rows that the grid item should span..cell-1 { grid-column: 2 / span 2; /* span 2 columns */ grid-row: 1 / span 2; /* span 2 rows */ }
-
We can also name the grid lines and use the names to place the grid items (💡 this can be useful when changing the grid layout in media queries)
.container { display: grid; grid-template-columns: [start] 100px [main] 1fr [end]; grid-template-rows: [top] 100px [main] 1fr [bottom]; } .item { grid-column: start / end; grid-row: top / bottom; }
-
Notes:
-
we can use negative values for row/column to point to the end of the explicit grid (not the implicit grid), it's also a future-proof way to span the grid items to the end of the grid container if we decide to add more columns/rows in the future
.cell-4 { grid-column: 1/-1; /* start on column 1 and end on the last column */ grid-row: 3/-1; /* start on row 3 and end on the last row of the explicit grid */ }
-
If you provided
grid-column-startorgrid-row-startwithoutgrid-column-endorgrid-row-end, the item will span only one cell -
If you provided
grid-column-endorgrid-row-endwithoutgrid-column-startorgrid-row-start, the item will span all the cells from the start to the end -
If you provided
grid-columnorgrid-rowwith only one value, the item will span to the end of the grid in that direction
-
In Flexbox,
align-itemsis used on the parent to control the cross-axis position for all of the elements. But we also havealign-self, which allows a specific child to overrule it.In CSS Grid,
align-selfworks pretty much the same way. We apply it to specific grid children, and it changes their vertical position within the grid cell. We also havejustify-self, which changes a particular element's horizontal position, within the grid cell
justify-self=> aligns the grid item along the row axis

align-self=> aligns the grid item along the column axisplace-self=> shorthand forjustify-selfandalign-self
grid-area property is used to assign a grid item to a grid area, or to create a named grid area.
-
grid-areais a shorthand property that sets all of the following properties in a single declaration:grid-row-start,grid-column-start,grid-row-end, andgrid-column-end..item { grid-area: 1 / 1 / 2 / 3; /* same as */ grid-row-start: 1; grid-column-start: 1; grid-row-end: 2; grid-column-end: 3; }
-
it specifies a grid item's size and location in a grid layout
grid-area: 2 / 1 / span 2 / span 3;=> start on row 2 column 1, and span 2 rows and 3 columns
-
It's also used with
grid-template-areasto name the grid areas-
if there is a column you want it to be empty => use
"."instead of the area name.container { display: grid; grid-template-areas: 'header header header' 'sidebar . main' 'footer footer footer'; } .header { grid-area: header; }
-
-
fr-
It stands for (fraction of the available space) of the grid-container and used to specify the size of the columns and rows in the grid by dividing the available space into fractions (instead of using
pxor%)
-
If we have multiple columns with
frunit, the space will be divided equally between them or based on the value of thefrunit
-
Examples
/* useful when you don't want to calculate the width-percentages of the columns/rows manually */ .container { display: grid; grid-template-columns: 1fr 1fr; /* same as */ grid-template-columns: 50% 50%; grid-template-rows: 2fr 1fr 1fr; /* same as */ grid-template-rows: 50% 25% 25%; }
-
It's similar to the
flex-growproperty in Flexbox -
it makes the cells responsive as they take the remaining space available relative to the current viewport size
-
It's used when we want our columns to grow and shrink based on the available space in the grid container, unlike percentage
%which is based on the viewport size (fixed size) -
Grid row
frweirdness-
What happens, though, if we use it for rows on a grid container without an explicit height (like
100vhor0height)? -
Answer: The
frunit will take up the remaining space in the grid container, but it will not take up the remaining space in the viewport. It will take up the remaining space in the grid container, which is the space that's left after the explicit rows have been laid out (the space that the grid-items take up).
-
-
frbeatsauto, when they are together (asautowill take the required space available for its content)
autowill take only its width andfrwill take all remaining space left
-
-
auto- is greedy (take the required space available for its content + the remaining space)
- it makes the cell responsive as it takes the remaining space
- it's the default behavior in implicit grids
-
min-content-
It's a keyword that specifies the smallest size a grid item can be while still fitting its content.
.container { display: grid; grid-template-columns: min-content 1fr; /* the first column will be at least the size of its content */ }
-
It's similar to
autobut with a minimum size limit
-
-
max-content-
It's a keyword that specifies the largest size a grid item can be while still fitting its content.
.container { display: grid; grid-template-columns: max-content 1fr; /* the first column will be at most the size of its content (the size of the longest word in the column-cells) */ }
-
They're used to create responsive grids that adapt to the size of the viewport and wrapping columns into new rows when needed.
They're used in the
grid-template-columnsandgrid-template-rowsproperties
-
auto-fill&auto-fitThey are used to create responsive grids that adapt to the size of the viewport and wrapping columns into new rows when needed.
- They are used as a replacement for explicitly define the size of the grid container and number of columns in the grid, by trying to fit as many columns as possible in the available space.
- Here, we don't define the grid container size (number of columns / rows), but we define the size of the columns and the number of columns will be created based on the available space.
- Use them when you don't know the size of page or the number of items that will occupy the grid but you know the width of columns.
- They can be used as the first argument in the
repeat()function to create a responsive grid layout.
-
auto-fill-
Generates as many columns as possible, even if they are empty (as long as there's space available).
-
Keeps the available space reserved without altering the grid items' width.
.container { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }
-
Ex:
-
If the container is
450pxwide, we can fit exactly 3 columns at150px, and there's no leftover space. -
If the container is
480pxwide, we can still only fit 3 columns, but there's30px of leftover space. Each column gets10pxwider, so that we have 3 columns that are160pxwide, perfectly filling the480px-wide container. -
If the container is
600pxwide, we can fit 4 columns at150px, and there's no leftover space.Note: This is a slight oversimplification. The real algorithm subtracts additional space like
gaporpaddingfrom the calculations, and supports having different columns of different proportions. But this is the basic idea!
-
-
-
auto-fit -
-
Let's suppose that we're rendering a dynamic list of data. We might have 20 items, or 40 items, or 2 items.
- In this particular case, we only have 2 items, but they're rendered in a very-wide grid. Let's say we have space for 6 columns
- What should happen? Should we create 4 additional empty columns, so that our 2 items stay approximately the same size as they would be if we had 20 items? Or should we create 2 super-wide columns that span the entire area?
- This is the fundamental difference between auto-fill (lots of empty columns) and auto-fit (stretched ultra-wide columns).
-
People almost always use auto-fill. since it ensures consistency in my grid no matter how many items I have. But if you want to make sure the elements span 100% of the available space, auto-fit has you covered.
-
auto-fill- will keep the available space reserved without altering the grid items width.
- generates as many columns as possible, even if they are empty (as long as there's space available)
-
auto-fitkeyword will expand the grid items to fill the available space.-
That being said, using
auto-fitmight lead to grid items being too wide, especially when they are less than expected. Consider the following example..wrapper { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); grid-gap: 1rem; }
-
-
-
Another ways to make Grid responsive:
-
The responsive way
-
We can always use a media query to change the number of columns in the grid (grid structure) based on the viewport size.
@media (max-width: 600px) { .container { grid-template-columns: 1fr; /* when the viewport is smaller, we stick with one column */ } }
-
-
The fluid ways
-
Use combination of (
vh,vw,%) units for the grid container size withminmax()function for the columns/rows andauto-fillorauto-fitfor the number of columns/rows.container { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(400px, 100%), 1fr)); }
-
Here's a breakdown of the code:
-
minmax(min(400px, 100%), 1fr)=> the column width will be at least400pxand at most100%of the viewport width.- 100% refers to the .grid element's width. If we're viewing this on a large monitor, .grid might be
800pxwide, so 100% resolves to800px. min()picks the smaller of the two values, so on a large monitor,400pxis returned from this expression. (We used it to handle the case when the viewport is smaller than400pxto prevent the grid from overflowing)- On a smaller screen, however, 100% might only be
250px. In this case, 100% is returned, since it's smaller than the alternative400pxoption.
- 100% refers to the .grid element's width. If we're viewing this on a large monitor, .grid might be
-
repeat(auto-fill, ...)=> the grid will create as many columns as possible, even if they are empty, as long as there's space available.
-
-
-
Set a fixed width / height for the grid, and use
frfor the columns / rows.container { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; }
-
-
-
minmax()-
it lets you define a minimum and maximum size (range) for column width or row height

-
It's used to prevent grid cells from getting too small / big
-
It's common to set the
minas fixed value and themaxas (frorautoor percentage%) to ensure that the track expands and takes up the available space (make the grid responsive).container { display: grid; grid-template-columns: minmax(100px, 1fr) 1fr; /* the first column will be at least 100px and at most 1fr */ }
-
-
repeat()-
It lets you repeat the same value multiple times in a
grid-template-columnsorgrid-template-rowsdeclaration to prevent you from writing out the same value over and over again..container { display: grid; grid-template-columns: repeat(3, 1fr); /* same as */ grid-template-columns: 1fr 1fr 1fr; }
-
-
fit-content()-
It lets you define the size of a grid track based on the size of its content.
- It's useful when you want to make a grid cell as big as its content, but not bigger than a certain value.
.container { display: grid; grid-template-columns: repeat(3, fit-content(100px)); /* 3 columns with at most 100px */ }
-
It's similar to
autobut with a maximum size limit
-
-
Explicit Grid: The grid that you define using both
grid-template-columnsandgrid-template-rowswith explicit values..container { display: grid; grid-template-columns: 100px 150px 200px; grid-template-rows: 50px 50px; }
-
But what will happen if the grid has
7items and you defined the grid with (3columns and2rows) ?- The grid will create implicit rows to accommodate the content, but they will have a height of
auto(the height of the content inside them or the explicit height of the items) - so the browser creates a 4th row and squeezes it in. It doesn't cause an overflow, it just means that there's less available space for the other elements.
- To control the height of the implicit rows, you can use the
grid-auto-rowsproperty
/* control the height of the implicit rows */ .container { display: grid; grid-template-columns: 100px 150px 200px; grid-template-rows: 50px 50px; grid-auto-rows: 100px; /* the height of the implicit rows */ }
- The grid will create implicit rows to accommodate the content, but they will have a height of
-
-
Implicit Grid: The grid that is created automatically to accommodate the content when there are more items than the number of columns/rows defined in the explicit grid.
- By default, it creates 1 new row for each element. if our grid parent has 3 children, we'll wind up with a 1x3 grid with 3 rows (auto height) and 1 column (auto width).
- Implicit grids want to fill the available space. Notice that the elements stretch across the horizontal space like block-level elements in Flow.
It's a feature that allows you to create a grid within a grid. It's used to create a nested grid layout where the child grid inherits the tracks of the parent grid.
-
For example: let's say that we have a list of items, and we want each list item to be assigned to our CSS Grid:
<div class="grid"> <header>Header</header> <aside>Sidebar</aside> <ul> <li>First Item</li> <li>Second Item</li> </ul> </div>
-
Our 3 grid children will be
header,aside, andul. In the 1st version of CSS Grid, thelielements can't participate in the grid, since they're grandchildren, not children, of the grid container. -
CSS Grid v2 introduces subgrid, a keyword that allows us to let grandchildren access the grid structure.
-
-
Grid Quirks
- Grids are limited to
1000rows, if a grid is given1002rows, the last3rows will occupy the same cell in the1000throw.- Update: Starting in Chrome 96, expected to release in early 2022, the grid row limit will be bumped to
100,000rows! That said, we shouldn't actually try and render that many items; Google recommends not exceeding1500DOM nodes, on the entire page! If you have a massive dataset that you want to render, you can use virtualization.
- Update: Starting in Chrome 96, expected to release in early 2022, the grid row limit will be bumped to
- "Margin collapse" doesn't work in CSS Grid. If you have a grid item with a margin, it won't collapse with the margins of its siblings. (same as Flexbox)

- Z-index works with grid children: A grid child can use z-index even if it doesn't change the
positionproperty. - Weirdness with “
fr” unit on rows: Thefrunit allows us to divvy up extra space in a grid container. This makes sense when we use it in ourcolumns, and it makes sense when we use it onrowswithin a specified-height container… but things get a little strange in other situations:
- Grids are limited to
-
If you have 3 items and you want to place the second item in the middle and the other items on the sides, you can use the following code:
.container { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; } .item-1 { justify-self: start; } .item-3 { justify-self: center; }
- by using
1frfor the first and last columns, the middle column will be placed in the middle of the grid container - by using
align-items: center;the items will be centered vertically, and by usingjustify-self: start;andjustify-self: center;the items will be placed on the (sides of their columns)
- by using
-
For tricky designs, always consider using more columns like
6or12to make the layout more flexible and easier to manage. -
To center a Grid-container, you can use these 2 options:
.grid-container { display: grid; /* option 1 */ align-items: center; justify-content: center; /* option 2 */ place-items: center; }
-
it's preferred to use
frover the percent unit%, using the%unit for columns/rows in addition togapwith px values would result mismatch calculations.container { display: grid; /* correct */ grid-template-columns: 1fr 1fr; /* wrong */ grid-template-columns: 50% 50%; grid-gap: 50px 100px; }
-
overlapping grid items
-
CSS-Grid allows cells to overlap with each other if you specify the same grid lines for the start and end of the grid item.
-
This is common when we have images stacked on top of each other, or when we want to create a layout where some items overlap with each other.

-
Example
.item-1 { grid-column: 1 / 3; grid-row: 1 / 3; } .item-2 { grid-column: 2 / 4; grid-row: 2 / 4; }
-
-
Question: when should you use flexbox and when should you use CSS Grid?
- Use Flexbox when you want to create a layout in one dimension (either a row or a column). ex: Navbar with a logo and links
- Use CSS Grid when you want to create a layout in two dimensions (both rows and columns). ex: Main layout of the page with a header, sidebar, main content, and footer (boxes or sections)
-
If you want to apply grid in an old browser, you can use:
- a fallback layout using Flexbox or other layout techniques -> Graceful Degradation
- tricks here
-
When we position an element, either using
grid-areaorgrid-column/grid-row, its DOM order doesn't matter. At least, it doesn't matter visually. But when it comes to keyboard navigation, the DOM order still calls the shots. -
Good grid recourses:
This layout is used to divide the content of an element into multiple columns. It's useful when you want to create a newspaper-like layout.
-
-
It specifies the number of columns an element should be divided into.
-
It can have the following values:
auto-> the browser will determine the number of columns2-> the element will be divided into two columns3-> the element will be divided into three columns
p { column-count: 3; column-gap: 20px; }
-
-
It's not only used for text, but also for images and other elements.
<ul> <li><img src="image1.jpg" alt="image1" /></li> <li><img src="image2.jpg" alt="image2" /></li> <li><img src="image3.jpg" alt="image3" /></li> <li><img src="image4.jpg" alt="image4" /></li> <li><img src="image5.jpg" alt="image5" /></li> <li><img src="image6.jpg" alt="image6" /></li> </ul> <style> ul { column-count: 3; column-gap: 20px; } img { width: 100%; margin-bottom: 20px; } </style>

















































