Skip to content

Responsive design

Edward Lu edited this page Feb 7, 2023 · 3 revisions

Why use responsive design

When designing components it's important to keep in mind that users have different screen sizes which can affect how elements appear on their page. Setting height, width, or positions to fixed values (i.e. hard-coding) can have unintended consequences as a result. Components should be styled in a way that changes dynamically in response to their container.

Flexbox and CSS Grid

The easiest way to achieve a responsive design is by using Flexbox and/or CSS grid. Read more:

Example (using flex-grow):

Here we are separating the items in this header component into two groups, one on the left and one on the right.

image

In the parent component we use the following:

.controls {
  display: flex;
  justify-content: center;
}

This will line up all the child components horizontally and align each item on the center horizontal axis.

In the center we use a filler element that grows and shrinks depending on the width of the parent. To do this we use the flex-grow property.

.filler {
   flex-grow: 1;
}

Now the two groups of items will be properly separated even when the size of the item changes.

image

Example (setting height dynamically):

Here the content element's height needs to equal the height of its parent (which is the height of the screen) minus the height of the toolbar + spacing. The toolbar is 3.5rem tall and the spacing is 1rem.

image

We want to avoid specifying an exact height since this value will change depending on the viewport. In order to set the height dynamically we use the calc function:

.content {
   margin-top: 1rem;
   height: calc(100% - 4.5rem);
}

Example (CSS Grid):

We want to lay out the row element of this form in the following way:

image

The HTML:

image

In the parent component we specify names of columns and set each column width:

.row {
    display: grid;
    grid-template-columns: [checkbox] 1.5rem [type] auto [size] 3.5rem [color] 3.5rem;
}

Then we place each child component into a column using grid-column:

.size-label {
    grid-column: size;
}
.color-label {
    grid-column: color;
}
.checkbox {
    grid-column: checkbox;
}
.type {
    grid-column: type;
}
.size-input {
    grid-column: size;
}
..color-input {
    grid-column: color;
}

Finally, the divider. We use grid-column to place the divider at the beginning of column 1, and extend it to the end of the row:

image

.divider {
    grid-column: 1/-1;
    margin: 1.5rem 0;
}