What is difference between justify-self, justify-items and justify-content in CSS grid?
To answer your questions:
1
As reiallenramos mentioned, "The justify-self and justify-items properties are not implemented in flexbox. This is due to the one-dimensional nature of flexbox, and that there may be multiple items along the axis, making it impossible to justify a single item. To align items along the main, inline axis in flexbox you use the justify-content property." - MDN
2-3
This screen shot from W3 does an excellent job of showing what they do and the differences between them.
Good To Knows:
For more information and example, I would suggest you check out:
- https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Box_Alignment_in_CSS_Grid_Layout
- https://www.smashingmagazine.com/2017/06/building-production-ready-css-grid-layout/
- https://www.smashingmagazine.com/2017/12/grid-inspector/
And for some inspiration:
- https://www.smashingmagazine.com/2017/10/css-grid-challenge-2017-winners/
In CSS Flexbox, why are there no justify-items and justify-self properties?
Methods for Aligning Flex Items along the Main Axis
As stated in the question:
To align flex items along the main axis there is one property:
justify-content
To align flex items along the cross axis there are three properties:
align-content
,align-items
andalign-self
.
The question then asks:
Why are there no
justify-items
andjustify-self
properties?
One answer may be: Because they're not necessary.
The flexbox specification provides two methods for aligning flex items along the main axis:
- The
justify-content
keyword property, and auto
margins
justify-content
The justify-content
property aligns flex items along the main axis of the flex container.
It is applied to the flex container but only affects flex items.
There are five alignment options:
flex-start
~ Flex items are packed toward the start of the line.flex-end
~ Flex items are packed toward the end of the line.center
~ Flex items are packed toward the center of the line.space-between
~ Flex items are evenly spaced, with the first item aligned to one edge of the container and the last item aligned to the opposite edge. The edges used by the first and last items depends onflex-direction
and writing mode (ltr
orrtl
).space-around
~ Same asspace-between
except with half-size spaces on both ends.
Auto Margins
With auto
margins, flex items can be centered, spaced away or packed into sub-groups.
Unlike justify-content
, which is applied to the flex container, auto
margins go on flex items.
They work by consuming all free space in the specified direction.
Align group of flex items to the right, but first item to the left
Scenario from the question:
making a group of flex items align-right (
justify-content: flex-end
)
but have the first item align left (justify-self: flex-start
)Consider a header section with a group of nav items and a logo. With
justify-self
the logo could be aligned left while the nav items stay
far right, and the whole thing adjusts smoothly ("flexes") to
different screen sizes.
Other useful scenarios:
Place a flex item in the corner
Scenario from the question:
- placing a flex item in a corner
.box { align-self: flex-end; justify-self: flex-end; }
Center a flex item vertically and horizontally
margin: auto
is an alternative to justify-content: center
and align-items: center
.
Instead of this code on the flex container:
.container {
justify-content: center;
align-items: center;
}
You can use this on the flex item:
.box56 {
margin: auto;
}
This alternative is useful when centering a flex item that overflows the container.
Center a flex item, and center a second flex item between the first and the edge
A flex container aligns flex items by distributing free space.
Hence, in order to create equal balance, so that a middle item can be centered in the container with a single item alongside, a counterbalance must be introduced.
In the examples below, invisible third flex items (boxes 61 & 68) are introduced to balance out the "real" items (box 63 & 66).
Of course, this method is nothing great in terms of semantics.
Alternatively, you can use a pseudo-element instead of an actual DOM element. Or you can use absolute positioning. All three methods are covered here: Center and bottom-align flex items
NOTE: The examples above will only work – in terms of true centering – when the outermost items are equal height/width. When flex items are different lengths, see next example.
Center a flex item when adjacent items vary in size
Scenario from the question:
in a row of three flex items, affix the middle item to the center of the container (
justify-content: center
) and align the adjacent
items to the container edges (justify-self: flex-start
and
justify-self: flex-end
).Note that values
space-around
andspace-between
onjustify-content
property will not keep the middle item centered in relation to the container if the adjacent items have different widths (see demo).
As noted, unless all flex items are of equal width or height (depending on flex-direction
), the middle item cannot be truly centered. This problem makes a strong case for a justify-self
property (designed to handle the task, of course).
#container { display: flex; justify-content: space-between; background-color: lightyellow;}.box { height: 50px; width: 75px; background-color: springgreen;}.box1 { width: 100px;}.box3 { width: 200px;}#center { text-align: center; margin-bottom: 5px;}#center > span { background-color: aqua; padding: 2px;}
<div id="center"> <span>TRUE CENTER</span></div>
<div id="container"> <div class="box box1"></div> <div class="box box2"></div> <div class="box box3"></div></div>
<p>The middle box will be truly centered only if adjacent boxes are equal width.</p>
What is the purpose of flex-start and flex-end on justify-items and justify-self?
This is an error. The justify-items
and justify-self
properties do not apply in flexbox.
Consider your source of information: MDN Web Docs (formerly Mozilla Developer Network). This resource, although normally useful and reliable, nonetheless represents second hand information.
The CSS definitions on MDN pages are based on official W3C documentation. MDN contributors (people) read, filter and interpret W3C data for presentation on MDN. As a result, MDN info is subject to human error. That's the problem here.
If you go directly to the spec, you'll find the correct information:
7.1. Inline/Main-Axis Alignment: the
justify-items
propertyThis property specifies the default
justify-self
for all of the
child boxes (including anonymous boxes) participating in this box’s
formatting context.
Okay. So let's go to justify-self
.
6.1. Inline/Main-Axis Alignment: the
justify-self
propertyApplies to: block-level boxes, absolutely-positioned boxes, and grid items
As noted, justify-items
and justify-self
do not apply to flex items.
Also note that justify-items
and justify-self
are applicable to multiple box models, not just CSS Grid. For more details see the CSS Box Alignment Module specification.
What is the difference between align-items vs. align-content in Grid Layout?
Let's start with clarifying the terminology:
Grid Container
The grid container is the overall container for the grid and grid items. It establishes the grid formatting context (as opposed to another formatting context, such as flex or block).
Grid
The grid is a group of intersecting vertical and horizontal lines that divides the grid container’s space into grid areas, which are boxes that contain grid items.
Grid Items
Grid items are boxes in a grid container that represent in-flow content (i.e., content that is not absolutely positioned).
Here's an illustration from the W3C:
The justify-content
and align-content
properties align the grid.
The justify-self
, justify-items
, align-self
and align-items
properties align the grid items.
With regard to the problem described in your question:
My confusion revolves around the claim made by the author that the "
-content
" set are there because: "Sometimes the total size of your grid might be less than the size of its grid container"
Well, you can see in the illustration that the grid is smaller than the grid container.
As a result, there is space remaining and the container is able to distribute this space to vertically center (align-content: center
) and right-align (justify-content: end
) the grid.
The extra space could also allow the grid to be spaced apart with values such as space-around
, space-between
and space-evenly
.
However, if the grid size equaled the container size, then there would be no free space, and align-content
/ justify-content
would have no effect.
Here's more from the spec:
10.3. Row-axis Alignment: the
justify-self
andjustify-items
propertiesGrid items can be aligned in the inline dimension by using the
justify-self
property on the grid item orjustify-items
property
on the grid container.10.4. Column-axis Alignment: the
align-self
andalign-items
propertiesGrid items can also be aligned in the block dimension (perpendicular
to the inline dimension) by using thealign-self
property on the
grid item oralign-items
property on the grid container.10.5. Aligning the Grid: the
justify-content
andalign-content
propertiesIf the grid’s outer edges do not correspond to the grid container’s
content edges (for example, if no columns are flex-sized), the grid
tracks are aligned within the content box according to the
justify-content
andalign-content
properties on the grid
container.(emphasis added)
Does it make any sense to use `baseline` value with `justify-content`, `justify-items` or `justify-self` in CSS Flex/Grid?
The MDN is not accurate here as there is no baseline for justify-content
If you check the actual Flexbox specification you will see that there is no baseline
value for justify-content
Value: flex-start | flex-end | center | space-between | space-around
In the near future and as defined in the CSS Box Alignment Module Level 3 we will have more generic way to align elements and even there baseline
is a not a valid value of justify-content
Value: normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]
<content-distribution> = space-between | space-around | space-evenly | stretch
<overflow-position> = unsafe | safe
<content-position> = center | start | end | flex-start | flex-end
By the way, there is baseline
for justify-items
in the new specificiation: https://drafts.csswg.org/css-align-3/#propdef-justify-items but this property doesn't exist in the actual Flexbox specification (same for justify-self
)
Related: In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
align-content
doesn't accept baseline
with Flexbox (https://drafts.csswg.org/css-flexbox-1/#align-content-property) but it does in the New Specification
The same apply for CSS grid but you can find justify-items
and justify-self
there: https://www.w3.org/TR/css-grid-1/#row-align
Actually I don't have a clear example to illustrate the baseline
with those properties but I am pretty sure in most of the case it will consider a fallback value as defined in the Spec:
Unexpected behaviour of grid items using justify-content property
From the specification
If the grid’s outer edges do not correspond to the grid container’s content edges (for example, if no columns are flex-sized), the grid tracks are aligned within the content box according to the justify-content and align-content properties on the grid container.
So if any column is using 1fr
, justify-content
is useless.
To use easy words: You grid container contain tracks (columns) that are sized either based on grid-template-columns
or automatically. When using 1fr 1fr 1fr 1fr
You define 4 equal tracks taking all the available space. There is no free space so there is nothing to align because justify-content
align the columns not the item inside them (that are equal to 20px).
When you don't define any size, the columns will get auto sized based on their content and in this case you will have tracks having their size equal to 20px
and inside them items also equal to 20px
. In this case, justify-content
will align your columns.
Worth to note that the default alignment is stretch so in the second case if you omit the justify-content
, your auto sized column will be stretched to fill all the space equally to have a similiar behavior as 1fr
.
to better understand, here is some illustration:
.grid {
display: grid;
grid-auto-flow: column;
justify-content: start;
margin: 1em;
background-color: powderblue;
}
.grid__item {
width: 20px;
padding: 0.6em;
background-color: lime;
}
4 equal columns
<div class="grid" style="grid-template-columns: 1fr 1fr 1fr 1fr">
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
</div>
4 equal columns having 100px width (we have free space)
<div class="grid" style="grid-template-columns: 100px 100px 100px 100px">
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
</div>
we align the items inside the columns
<div class="grid" style="grid-template-columns: 100px 100px 100px 100px;justify-items:center">
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
</div>
<div class="grid" style="grid-template-columns: 100px 100px 100px 100px;justify-items:end">
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
</div>
we move the columns to the end
<div class="grid" style="grid-template-columns: 100px 100px 100px 100px;
justify-content: end;justify-items:end">
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
</div>
We make the column auto sized (nothing to align inside them)
<div class="grid" style="justify-items:center">
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
</div>
<div class="grid" style="justify-items:end">
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
<div class="grid__item">item</div>
</div>
justify-content works differently in Flex and Grid layouts
In flex layout, the justify-content
property distributes free space in the container between or around flex items (depending on the value).
8.2. Axis Alignment: the
justify-content
propertyThe
justify-content
property aligns flex items along the main axis
of the current line of the flex container. ... Typically it helps
distribute extra free space leftover when either all the flex items on
a line are inflexible, or are flexible but have reached their maximum
size.
In grid layout, the justify-content
property distributes free space in the container between or around grid columns (depending on the value).
Note the difference with flex: Here, justify-content
aligns grid columns, not grid items.
10.5. Aligning the Grid: the
justify-content
andalign-content
propertiesIf the grid’s outer edges do not correspond to the grid container’s
content edges (for example, if no columns are flex-sized), the grid
tracks are aligned within the content box according to the
justify-content
andalign-content
properties on the grid
container.
Here are the grid column tracks in your layout...
...without justify-content: space-between
:
...and with justify-content: space-between
:
Here's a related post that may help with further understanding:
- What is the difference between align-items vs. align-content in Grid Layout?
Related Topics
Ie7 Z-Index Issue - Context Menu
Css Transition Shorthand With Multiple Properties
Should I Use 'Border: None' or 'Border: 0'
Fixed Sidebar Navigation in Fluid Twitter Bootstrap 2.0
Top Nav Bar Blocking Top Content of the Page
Difference Between Background and Background-Color
How to Select All Children of an Element Except the Last Child
How to Style a Div to Be a Responsive Square
How to Reset/Remove Chrome'S Input Highlighting/Focus Border
Google Chrome Extensions - Can't Load Local Images With Css
Style Child Element When Hover on Parent
Changing :Hover to Touch/Click For Mobile Devices
Sass - Use Variables Across Multiple Files
Eliminate Flash of Unstyled Content