Mastering Front Knowledge CSS-8
- web
- study
- front
- CSS
Let's understand layout now.
1. Introduction to Layout
1.1. Normal Flow
This is the default behavior when the page layout is not manipulated at all. Elements are arranged sequentially in a block direction. This block direction refers to vertical placement in horizontal writing languages like English.
When creating layouts with CSS, we move elements away from this normal flow. Layouts can be created using display, float, position, and table (though the latter is not recommended).
1.2. Overview of Display Property
We learned that the display property determines block and inline elements, and can be changed arbitrarily. However, there are other properties as well.
Setting display:flex
makes all direct children flex items. This can be conveniently used to arrange items in one-dimensional concepts like rows or columns. This allows us to determine how to arrange internal children through properties like flex-direction
.
Setting display:grid
makes all direct children grid items. This is convenient for placing items in a two-dimensional concept. In this case, properties like grid-template-rows
can be used to determine the placement of internal children.
In a grid display, the parent element can specify properties for rows and columns, as well as gaps between cells, allowing child elements to automatically position themselves within. Of course, it is also possible to directly position child elements using properties like grid-row
.
1.3. Overview of Float Property
The float property allows an element to be placed outside the normal flow to the left or right. The rest of the page content will flow around the floated element, which can be useful for creating layouts.
.box {
// Floats the element to the left. Following elements will float around the box class element.
float: left;
}
1.4. Overview of Position Property
Using the position property allows elements to be moved away from their original placement. There are five types.
position:static
is the default, placing elements according to normal flow.
position:relative
places elements based on normal flow, but allows adjustments using the top, right, bottom, and left properties. Overlapping with other elements is also possible.
position:absolute
removes elements from normal flow and positions them relative to the nearest ancestor element or the html element. Naturally, it can overlap other elements within the same parent.
position:fixed
is similar to absolute, removing the element from normal flow and positioning it relative to the browser viewport. It remains in a fixed position regardless of scrolling.
position:sticky
behaves like static until a defined viewport point is reached, then acts like fixed. This means it will remain visible at the same position after a certain point in scrolling.
1.5. Multi-column Layout
A multi-column layout organizes the page into several columns, similar to a newspaper article. To create a multi-column container, specify the number of columns with column-count
or the width of the columns with column-width
.
2. Normal Flow
Normal flow is the way elements are laid out when there has been no alteration to the layout. The arrangement style depends on the parent's writing mode (writing-mode property), but generally, it can be considered horizontal placement.
Block elements stack vertically and appear with line breaks. They are separated by the margin of each element. If both adjacent elements have margins, only the larger value remains.
Inline elements stack horizontally and appear without line breaks. However, if there is insufficient space, overflowing text or elements will appear on a new line, as seen with the span
element.
3. Flexbox
Flexbox is a method for laying out elements in one dimension. Previously, page layouts were accomplished through floats or position properties.
3.1. Flexbox Structure
The flex model has the structure shown above.
The parent element with display:flex
is the flex container, and the child elements arranged within are called flex items.
The main axis is the axis that starts at the main start of the container and progresses towards the main end. Flex items are arranged along this axis. The cross axis is the axis perpendicular to the main axis.
3.2. Flexbox Properties
flex-direction
can be set to row, column, row-reverse, or column-reverse. This property determines the direction of the main axis. The reverse option simply reverses the direction of the main axis.
flex-wrap
can be set to nowrap, wrap, or wrap-reverse. The default nowrap places all flex items in a single row, overflowing if there is not enough space. Wrap moves to the next line when all flex items cannot fit in one row. Wrap-reverse is similar to wrap but arranges items in the opposite direction.
Setting flex-flow
allows you to specify both flex-direction and flex-wrap in one go, such as flex-flow:row wrap;
.
3.3. Exploring the Flex Property
The flex property is a shorthand for flex-grow
, flex-shrink
, and flex-basis
. This property is applied to each item to specify how the item adjusts in size to fit the container space. Each of these properties is defined as follows.
3.3.1. Flex-grow
Flex-grow sets the method for distributing remaining space within the container when the combined width of items is less than the container width.
The space-filling method operates as follows. The base widths defined in flex-basis are allocated to all items. If there is remaining space, it is distributed according to the flex-grow values.
For example, if the HTML is defined as follows:
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
And the CSS is written this way:
.container {
display: flex;
flex-wrap: nowrap;
gap: 0;
padding: 10px;
background: aqua;
width: 600px;
}
.item {
flex-basis: 100px;
}
.item:nth-child(1) {
flex-grow: 1;
}
.item:nth-child(2) {
flex-grow: 2;
}
.item:nth-child(3) {
flex-grow: 3;
}
.item:nth-child(4) {
flex-grow: 4;
}
Then, the total width allocated for contents in the container is 600px. Each item receives 100px according to flex-basis. The remaining space is 200px.
This 200px of remaining space is divided according to the flex-grow ratios: the first item receives 1/10, the second 2/10, the third 3/10, and the fourth 4/10, resulting in widths of 120px, 140px, 160px, and 180px, respectively.
3.3.2. Flex-shrink
Flex-shrink does not apply when flex-wrap:wrap
is specified for the container. It sets the method by which items are reduced when their total width exceeds that of the container. In wrap mode, if item widths are too large, they simply move to the next line.
In any case, flex-shrink reduces exceeding elements based on the assigned values. If flex-shrink is set to 0, no reduction occurs. If the flex-shrink values are the same among sibling elements, they are reduced evenly to achieve the same size.
So, what happens if we set different flex-shrink values for each item? It works similarly to grow. The widths of items that exceed the container are reduced according to the ratios of their flex-shrink values.
For example, if there is an excess of 200px, and each item has flex-shrink values of 1, 2, 3, and 4, then item 1 will reduce its width by 20px, item 2 by 40px, item 3 by 60px, and item 4 by 80px.
3.3.3. Flex-basis
Flex-basis specifies the default size of an item before flex-grow and flex-shrink are applied. This size depends on the direction of the main axis: it is width if the main axis is row and height if it is column.
If flex-basis is set to auto, the size is determined based on the width or height specified on the item (also influenced by content). If set to content, the size is determined by the content, though content may not be supported in older browsers.
If flex-basis is 0, the default size of the item becomes 0. In this case, width allocation will occur based on flex-grow and flex-shrink values, as all portions are treated as margins.
Therefore, to make all items the same width regardless of their content, set flex-basis to 0 and flex-grow to 1.
3.3.4. Flex
Now, how does the shorthand flex work? Flex can be specified using 1 to 3 values.
-
When there's 1 value If a number is specified, it is for
flex-grow
. If a length (e.g., 100px) or ratio is specified, it is forflex-basis
. -
When there are 2 values The first value must be a number, representing
flex-grow
. The second can either be a number (forflex-shrink
) or a length or ratio (forflex-basis
). -
When there are 3 values The first value becomes
flex-grow
, the second becomesflex-shrink
, and the third becomesflex-basis
. Naturally, the first two must be numbers, and the third must be a length or ratio. -
Special Keywords
initial
causes the item to shrink to fit the container size if it exceeds, but otherwise follows its specified width and height, equivalent toflex:0 1 auto
. This is the initial value for flex.
auto
automatically determines the item's default size, allowing it to grow or shrink to fit the container, equivalent to flex:1 1 auto
.
none
automatically specifies and fixes the item's size, equivalent to flex:0 0 auto
.
3.4. Item Placement
justify-content
determines how items are positioned along the main axis. align-items
determines how items are aligned along the cross axis.
If flex-direction
is row, justify-content
specifies where items are placed along the row, while align-items
specifies their vertical alignment.
Individual item placements along the cross axis can also be specified using align-self
.
3.4.1. Justify-content Property
Other properties can generally be anticipated. space-around
evenly distributes all items along the main axis with slight spaces on both ends.
In contrast, space-between
distributes all items evenly along the main axis without leaving space on either end.
3.5. Order
Each flex item can have an order assigned. Items with lower order values are placed first, with the default being 0. For example, if an item's order is set to 1, it will be placed behind others.
Negative order values can also be used to position items ahead of those with default orders.
4. Grid
Grid layout allows elements on a page to be arranged in two dimensions. It divides the page into rows and columns, specifying which elements to place in which rows and columns. The grid display mode is specified as follows:
display: grid;
4.1. Basic Grid Creation
Rows and columns can be created using grid-template-columns
and grid-template-rows
. Using the fr
unit allows you to allocate the available space within the grid container to define the size of each row and column.
// Create 3 columns by splitting available width in a 1:2:1 ratio
grid-template-columns: 1fr 2fr 1fr;
// Create 3 rows by splitting available height in a 1:1:2 ratio
grid-template-rows: 1fr 1fr 2fr;
Spacing between rows and columns can be specified using grid-column-gap
and grid-row-gap
. You can also use grid-gap
to specify both at once (a shorthand for row-gap and column-gap) without the grid-
prefix.
The repeat()
function allows for easy specification of repeated rows/columns. For example, repeat(5, 1fr)
creates 5 rows or columns of size 1fr. There is also minmax()
for setting minimum and maximum sizes for each row or column.
grid-template-columns: repeat(5, minmax(50px, auto));
4.2. Automatically Setting Rows and Columns
Until now, we had to directly specify the number of rows when using grid-template-rows
. However, sometimes you may want to create as many rows as possible within the allowed size. In such cases, use auto-fill or auto-fit.
.container {
// Create as many 100px tall rows as possible
// If there is remaining height, simply move to the next line
grid-template-rows: repeat(auto-fill, 100px);
}
If you switch to auto-fit, when there is remaining space in the container, it will expand the existing row sizes to fill that space.
Using grid-auto-rows
and grid-auto-columns
specifies the sizes of rows/columns outside of those controlled by grid-template-
. If you specify only this property without grid-template-
, all rows/columns will be set to this property’s specified size.
// Automatically create rows and columns of size 100px
grid-auto-rows: 100px;
grid-auto-columns: 100px;
4.3. Grid Item Placement
You can specify which rows and columns each grid item will occupy using the grid-row and grid-column properties. You can also specify starting and ending lines like 1/3
.
Alternatively, you can use grid-row-start, grid-row-end, grid-column-start, and grid-column-end properties to specify the starting and ending lines for each item.
4.4. Grid-template-areas
An interesting fact is that using the grid-template-areas
property, you can name each grid element and arrange items using those names.
.container {
display: grid;
grid-template-areas:
"header header header"
"main main aside"
"footer footer footer";
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
}
// The header tag occupies grid areas named header
header {
grid-area: header;
}
main {
grid-area: main;
}
...
You can use the named grids to arrange items accordingly. Names assigned to areas must fill all cells in the grid. To leave a cell empty, you must include a .
.
Also, the named areas must form a rectangle, just like areas specified by row/column numbers, and must be unique.
References
flex property https://developer.mozilla.org/en-US/docs/Web/CSS/flex
flex 2 https://blogpack.tistory.com/863
https://velog.io/@garcon/Flexbox-flex-basis-auto%EC%99%80-0%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90
auto-fill and auto-fit https://velog.io/@iandr0805/CSS-Grid-auto-fit%EA%B3%BC-auto-fill%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90
good organization of grid https://studiomeal.com/archives/533