If you are a front-end developer or you work with one you are probably familiar with the occasional frustration when it comes to generating a layout for a web page. Why is it so hard to do such an essential thing? Isn't that what HTML and CSS were made for? Have we been breaking the Web all this time? Is there a better way?
Let's first examine the root of the problem. HTML was invented by Tim Berners-Lee at CERN around 1990s, and its purpose was to share documents with text and images accompanying the text. We were forced to use the technology that was made for such an essential purpose to create nice looking websites with elements positioned one next to another which additionally needed to adapt to different screen sizes because unfortunately, we lacked better tools for the job.
For years we have been using display:block/inline-block positioning and float to place one block to the left and then the other one next to it, but those were not made for that purpose. For example, the only purpose of the float is to float the content inside its context (float the image so the text can wrap around) and nothing else. Luckily now we have CSS Flexbox and Grid to help us build modern and responsive layouts.
CSS Flexbox Layout
The Flexbox Layout provides a more efficient way to lay out, align and distribute space among items in a container, which is especially important when their size is unknown or dynamic. With Flexbox it is suddenly easy, for example, to make a div element of a specific width and another one that will take up the rest of the free space. It's also easy to centre one or more elements or to spread them in the container with equal widths and gaps between them and much more. Once you define display: flex; on an element, it becomes a flex container, and all its direct children become flex items.
Various properties can be assigned to the flex container and each flex item. Some of those are flex-direction which lays out items either horizontally or vertically; flex-wrap which can make the items wrap on multiple lines instead of one line (default); justify-content with options to align the items to the start or end, centre them, create equal space between, create equal space around, etc. The most important property of flex item is flex which defines flex-grow, flex-shrink and flex-baseline. The default for flex is "0 1 auto".
Flex-grow defines what amount of the available space inside the flex container the item should take up. If all items have flex-grow set to 1, the remaining space in the container will be distributed equally to all children. If one of the children has a value of 2, the remaining space will take up twice as much space as the others. Flex-shrink gives the ability for flex item to shrink if necessary. Flex-basis defines the default size of an element before the remaining space is distributed. It can be a length in percentage, rem, pixels or other units, or a keyword like „auto“ which is a default.
CSS Grid Layout is a two-dimensional grid-based layout system explicitly created to solve the layout problems we've all been hacking our way around for as long as we've been making websites. At the moment it is the most powerful layout system available in CSS and unlike flexbox which is a 1-dimensional system (either vertical or horizontal direction), grid handles both rows and columns. It gives us an easy and intuitive way of making a responsive layout for our websites.
To start creating a grid, you need to define a container element as a grid, set the column and row sizes and then place its child elements into the grid. The order of HTML elements inside the grid container doesn't matter at all because you can use CSS to set them in any order and re-arrange the grid on different screen sizes with media queries.
Let me first show how easy it is to make a grid and then I'll briefly explain the meaning of the properties.
First, I made a container with four elements in HTML and then used CSS to arrange those elements inside a grid. For each item selected by a CSS class, I defined a name of the related grid area (header, name, sidebar, footer). For the container I defined:
display: grid; which defines the container as a grid container.
grid-template-columns: Defines columns in the grid with specified width. Width can be specified in pixels, percentage, with a keyword „auto“ or fractions „fr“. For example, if we specify grid-template-columns: 50px 50px 1fr 2fr; we will have two columns 50 pixels wide, and the other two will take up the free space – 3rd column will take 1 fraction and 4th column 2 fractions of the free space.
grid-template-rows: Defines rows in the grid with specified height (here it is simply set to „auto“).
grid-template-areas: Defines the order of the elements and how many cells should the element take up. We can already see from the CSS the structure of our grid. Repeating the name of a grid area causes the content to span those cells.
According to caninuse.com flexbox is supported in all major browsers and partially in IE10+. In IE it has a lot of bugs, and IE10 supports only the old syntax from 2012 with prefix „-ms-„. CSS Grid is also supported in all major browsers, but in IE it only supports the old specification.
Microsoft doesn't plan to update the specification in IE11, but they have released the new Edge 16 browser with the new Grid specification. You are probably thinking „Oh, that Microsoft is always lagging behind!“ but the interesting fact is that actually Microsoft was the one who proposed the original specification for the CSS Grid and the user interface for Windows 8 was made with it. Since the grid specification is in the core of their OS and Internet Explorer is one of the core apps it is almost impossible for them to change anything related to the grid in IE and not break other stuff. Even though it is possible to see the grid layout in most of the modern browsers, only Firefox Nightly, a browser updated every day with new code for testing before the code gets into a stable release, has tools aiming to help developers to work with the grid from the dev tools in the browser.
CSS finally provides front-end developers with the right tools for making responsive layouts without hacks and workarounds. CSS Flexbox and Grid are already supported in browser quite good, but it will take some time for developers to become comfortable with using them on production sites even though some prominent projects started using flex in new versions, like Bootstrap 4.
There are still things to be discovered by developers about these tools, what use-cases should they solve and also what they are missing. For example, at the moment of writing this post, it's not possible to animate the element when it dynamically spans from 1 to a couple of cells in a grid, but those things should not refrain us from using the Grid. This is a technology that will soon be a part of our standard workflow, and we should better start using it now to be prepared to create awesome websites for our products and clients later.