© Mikael Olsson 2019
Mikael OlssonCSS3 Quick Syntax Referencehttps://doi.org/10.1007/978-1-4842-4903-1_26

26. Layout

Mikael Olsson1 
(1)
Hammarland, Finland
 

There are many ways to create a layout in CSS. This chapter will look at some of these methods and how they compare when creating a simple layout.

Float

In the early days of CSS one of the few available methods for creating a grid-like design was to use the float property to get block elements to stay on the same line.
.left { float: left; }
.clear { clear: both; }
To show the effect of floating elements the following box style will be used.
.box {
  width: 100px;
  height: 100px;
  margin: 1em;
  background: #ccc;
}
Clearing issues and browser inconsistencies aside, the float property provided a non-intuitive way of defining a layout which has since long been deprecated as better methods became available. The floating layout defined here is illustrated in Figure 26-1.
<div class="left box"></div>
<div class="left box"></div>
<div class="clear"></div>
<div class="left box"></div>
<div class="left box"></div>
<div class="clear"></div>

Inline-Block

The inline-block display type offered several advantages compared with floating layouts, including greater simplicity and no need for clearing floats. Moreover, the layout won’t break when elements have different heights as they would with floating elements. The vertical-align property can be used to specify how elements align when their heights differ.
.inline {
  display: inline-block;
  vertical-align: top;
}
An issue with inline-block elements is that any whitespace around elements will be visible as gaps. Removing the whitespace, or moving the end tags around as seen here, solves the issue but makes the HTML less readable. The example given here produces the same result as seen in Figure 26-1.
<div>
  <div class="inline box">
  </div><div class="inline box"></div>
</div>
<div>
  <div class="inline box">
  </div><div class="inline box"></div>
</div>
../images/320834_2_En_26_Chapter/320834_2_En_26_Fig1_HTML.png
Figure 26-1

Floating layout

Multiple Columns

The multi-column layout allows content to flow into multiple columns, as in a newspaper. It is enabled by setting one or both of the following properties: column-count and column-width. The column-count property specifies the number of columns the content will break into, letting the browser divide their width equally. Conversely, the column-width property sets the fixed width of all columns, leaving the browser to work out how many columns will fit based on available screen width.
.flexible-cols {
  column-count: 3;
}
.fixed-cols {
  column-width: 14em;
}
Column boxes cannot be targeted individually in CSS so all columns must be the same size. A vertical line can be added between columns using the column-rule property, which behaves like the border property. The gap between columns can also be adjusted using the column-gap property. It can be changed to any valid length unit and is 1em by default.
.mycols {
  column-gap: 2em;
  column-rule: 1px solid #ccc
}

Support for the multi-column properties is available in Chrome 50+, Firefox 50+, Safari 10+, Opera 37+, and IE 10+. The -webkit- and -moz- prefixes can be used to extend support to Chrome 4+, Firefox 2+, Safari 3.1+, and Opera 11.5+.

Flexbox

The flexible box or flexbox module provides a simple way to create a fluid layout in one dimension, either a horizontal row or a vertical column. To enable the flexbox layout the flex display property is applied to the container element, called the flex container.
.flex-wrapper {
  display: flex;
}
Child elements of this container are called flex items. They are by default laid out according to text direction (typically left to right) in a row in the order they appear in the source document. Consider the following flex items.
.item1 {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 10em
}
.item2 {
  flex-grow: 3;
  flex-shrink: 2;
  flex-basis: 10em
}
The flex-basis property specifies that both items want to be 10em wide. Because of the flex-grow property, if the flex container is larger than 20em the second item will take up three times as much of the surplus space as the first item. In contrast, if the container shrinks to less than 20em width the second item will contract twice as much as the first item, as specified by the flex-shrink property. All three of these properties are normally defined using the flex shorthand property to make sure all values are set.
flex (flex): 0 1 auto | flex-grow + flex-shrink + flex-basis
If the space of the container becomes too narrow to fit the item’s flex-basis setting the container can be made to wrap to another row using the flex-wrap property.
flex-wrap (flex): nowrap | wrap | wrap-reverse
Each new row (or column) will become a new flex container distributing the space between items that wrap to that container. Items wrapped to the second row will not align with items on the first row.
.flex-wrapper {
  display: flex;
  flex-wrap: wrap;
}
Placed within the flex container these items will be evenly distributed on the horizontal axis even if the browser is resized, without any need for media queries, as seen in Figure 22-1.
<div class="flex-wrapper">
  <div class="item1 box"></div>
  <div class="item2 box"></div>
</div>
Flex items are by default laid out horizontally in the text direction in the order they appear in the source document. The direction of the flex container is determined by the flex-direction property, which can have one of four different values.
flex-direction (flex): row | row-reverse | column | column-reverse
Individual items can also be targeted to change their order using the order property, which is a unitless number that starts at 0 for the first item. When used together with media queries this can allow for items to be reshuffled if needed based on available screen size.
.item2 {
  /* Position before item1 */
  order: -1;
}
A feature of flexbox is that it becomes easy to properly align items using the align-items, align-self, align-content, and justify-content properties.
align-items (flex): stretch | flex-start | flex-end | center | baseline
align-self (flex): auto | flex-start | flex-end | center | baseline | stretch
The align-items property sets the main-axis alignment of all direct child flexbox items, which refers to vertical-alignment for horizontal flex boxes. This setting can be overridden on individual items using the align-self property.
.flex-wrapper {
  display: flex;
  /* Vertically align items to top */
  align-items: start;
}
.item1 {
  /* Stretch auto-sized item to container height */
  align-self: stretch;
}
Alignment of the secondary axis, which means horizontal alignment for a horizontal flexbox, is done using the justify-content property.
justify-content (flex): flex-start | flex-end | center | space-between | space-around | space-evenly
This property is applied to the flex container and affects all items.
.flex-wrapper {
  display: flex;
  /* Center items vertically */
  align-items: center;
  /* Center items horizontally */
  justify-content: center;
}
Lastly, the align-content property specifies how a flex containers lines will align when there is extra space available on the secondary axis. This will only have an effect when there are multiple lines in a flex container.
align-content: stretch | flex-start | flex-end | center | space-between | space-around
Each line height would by default stretch and be distributed evenly on the secondary axis, but the align-content property can change this behavior to for instance grouping the lines together in the middle of the flex container.
.flex-wrapper {
  display: flex;
  height: 100vh;
  flex-wrap: wrap;
  /* Align rows in center */
  align-content: center;
}

The flexbox properties are supported in all modern browsers, including: Chrome 29+, Firefox 22+, Safari 10+, Opera 48+, and IE 11+.

Grid Box

The grid module was designed for two-dimensional layouts, when there’s a need to control the layout by both row and column. Whereas a flexbox can adjust the number of items per row according to available space, the grid will always have the specified number of columns and rows. To start defining a grid layout the display value is set to grid. As with flexbox, this changes all direct children of the container into grid items.
.grid-wrapper {
  display: grid;
}
This will default to a one column grid, so the following items will look the same as they would in the normal flow with a single column and two rows.
<div class="grid-wrapper">
  <div class="box"></div>
  <div class="box"></div>
</div>
A grid layout can be either implicitly or explicitly defined. This grid here is implicit, because the number of rows and columns are not explicitly defined. The height of such rows can be set with the grid-auto-rows property.
grid-auto-rows (grid): auto | max-content | min-content | length
More columns can be added using the grid-template-columns property, with each specified value defining the size of a column as either a length value or a percentage.
.grid-wrapper {
  display: grid;
  grid-template-columns: 100px 100px;
  grid-auto-rows: 100px;
}
If an item taller than the row height is added, its content will overflow. To instead get a flexible height that expands to fit the content the minmax function can be used. This function sets the minimum and maximum height of a row (or width of a column) so that it can adjust automatically to the height of the content. The function can be used with the following grid properties: grid-template-columns, grid-template-rows, grid-auto-columns, and grid-auto-rows.
grid-auto-rows: minmax(100px, auto);
An explicit number of rows can be defined using the grid-template-rows property. Keep in mind that any items placed outside of an explicitly defined grid will automatically expand the grid.
grid-template-rows (grid): none | auto | max-content | min-content | length
One way to specify the size of a grid row or column is using the fractional unit denoted by fl. This unit represents a fraction of the available space in the grid container, so the following grid layout will have two rows with the first one taking up 40% of the available space and the second one taking up the remaining 60%. Note the repeat function used here as a simple way to specify four columns of equal width. It gives the same result as specifying the value auto four times.
.grid-wrapper {
  display: grid;
  height: 100vh;
  grid-template-rows: 2fr 3fr;
  grid-template-columns: repeat(4, 1fr);
}
There is a shorthand property named grid-template available for setting the grid-template properties all at once.
grid-template (grid): none | grid-template-rows / grid-template-columns | grid-template-areas
The following specifies a grid layout with two columns and one row with a 200px height.
.grid-wrapper {
  display: grid;
  grid-template: 200px / auto auto
}
Notice that the grid-template property has a possible value called grid-template-areas. This property provides an alternative way to define the grid layout by first naming the individual items with the grid-area property. The names can then be referenced to position them on the grid using the grid-template-areas property, as seen here. Keep in mind that an element can take up more than one cell on the grid.
.item1 { grid-area: header; }
.item2 { grid-area: menu; }
.item3 { grid-area: content; }
.item4 { grid-area: footer; }
.grid-wrapper {
  display: grid;
  grid-template-areas:
  'header header header'  /* row 1 */
  'menu content content'  /* row 2 */
  'footer footer footer'; /* row 3 */
}
Items normally appear on the grid in the order they are listed in the HTML. This placement can be changed using the grid-column and grid-row properties to designate where an item will appear. For example, the following styling places the header element so that it takes up the first two cells of the grid on the first row.
header {
  grid-column: 1 / 2;
  grid-row: 1;
}

Support for the grid layout properties is available in: Chrome 57+, Firefox 52+, Safari 10.1+, Opera 44+, and Edge 16+.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.81.240