Mini-tutorial on responsive layouts, part 3

Jan 9 2018

This is the third and the last part of the mini-tutorial. It touches on the subjects of tables and media queries, and lists some of the layout best practices we use in Spectory. If you haven't read the first two parts, here are the links: part 1 and part 2.

A word on HTML tables

As mentioned in the paragraph above, there are some layout problems that can be solved either by flexbox or by table layout.

What is table layout and why is it considered a bad practice?

Table layout is a way of arranging things on the page without any styles, and it was commonly used before CSS came into this world. The idea of using table tags was natural, as each layout is mostly an arranged grid, and table is a powerful tool for customizing grids. There are several problems with table layouts, though:

  • semantics; table tag is meant for displaying tabular data, not for arranging elements
  • cumbersome code, cluttered with tables inside tables inside tables, is very hard to read and support
  • table tag doesn't allow for rearranging cells for different resolutions, which makes it, against your initial intuition, not suitable for creating truly responsive layouts (three beautiful columns on large screens will become three uncomfortably narrow columns on small screens)

When is it okay to use tables?

On webpages table tag should be used for one purpose only - displaying tables. When building responsive layouts, almost always there are more efficient and elegant ways of doing it. That said, there are times you're left with two choices: flexbox and tables. And if you're reluctant to use the former, CSS provides a method of table-like layouting with just the styles - table- values of the display property (see all values here). It's preferable to the use of HTML tables.

And finally, tables can and should be used for email body layouts. The reason for such is that none of the mail clients support enough CSS for it to be used effectively, and different clients support different subsets of it, which makes it impossible to build email templates that work cross-client.

Media queries

The point of responsive layouts is to look good on any (supported) device, including tablets and mobile phones. Sometimes in order to look good on smaller screens, the content has to be rearranged on the page, and although flexbox gives us some means for rearrangement, using media queries is the preferred way of adjusting element styles depending on the screen sizes and types.

@media (max-width: 800px) {
  #sidebar {
    display: none;
  }
}

This code, appended to the end of the CSS file, will make sure that an element with id='sidebar' will stay hidden on screens with width of 800px and smaller. It's important to add @media queries to the bottom of the CSS files, so they will be loaded after the rest of the styles (and override them).

Complex queries

To create media queries with multiple conditions, use logical operators and, not and only.

@media (min-width: 30em) and (orientation: landscape) { ... } /* landscape-oriented screens of min width 30em  */
@media not screen and (color) { ... } /* negates the whole query: not (screen and (color)) */

The only keyword has no effect on modern browsers and is used for preventing the old ones from applying styles; it won't be discussed here.

Read more

Although media queries are mostly used for adjusting layouts, there are other uses. For a better overview of the @media rule and detailed syntax see the MDN docs.

Cross-browser support

It's important to stay mindful of people using different browsers when surfing the Web. One may prefer the conventional Google Chrome or Firefox, and another is used to Safari for Windows. The problem with this diversity is that rule interpretation can vary, to the point of not supporting some of them at all.

Some development time can be saved by using tools like caniuse.com which has updated charts of CSS feature support by different browsers and versions. Generally, if some of the modern browsers don't support a rule, it's best to avoid it.

Best Practices (by Gil Meir)

  • Keep your layout as nested contained boxes, if a parrent collapses or a child overflows, fix it!
  • Use namespaces via a preprocessor (i.e. SCSS) or simple dashes to avoid global namespace collisions.
  • Use calc to show where the numbers are coming from. Vars or custom properties (from preprocessor) are also great.
  • Prefer REMs and percentages for most stuff, EMs for margin/padding of elements with custom sized fonts and pixels as little as possible.
  • Escalate positioning: static -> relative -> absolute -> fixed.
  • Don't add rules to fix things, try to understand why the browser decided to draw things the way it did, most likely you need to change rules or even delete them.
  • Don't use negative values to position things unless you're using some well defined pattern explicitly.
  • Display table-cell and floats work really well for positioning things. Flex is also great with caution.
  • Devtools is part of the process, use them to gain insight into how the browser derives properties and to see things like reflows and repaints.
  • Always develop on more than one browser, it will expose mostly your mistakes.
  • Don't just rip things off of the web and paste them in your code, retrofit things to the style of the project.
  • Be very wary of properties with global significance such as z-index. Prefer selecting by class and never use inline styles or important. These make your code harder to manage.
  • Don't bother too much with abstractions, CSS does not compose well. Focus on separation, locality, cross-browser and minimal rule-sets.

Further reading

Masha K.
Software Developer
Back to Blog