CSS - Layout

Breaking Out with CSS Grid Layout

A side-by-side comparison of a narrow viewport and a wider one, with one grid item spanning the full width in the latter, while the rest are constrained via the centre column.

If you’ve ever needed to have a content column with a maximum width, but have specific elements span the full width of the viewport, thus breaking out of the column, CSS Grid can do this really simply. First the grid on the container:

CSS

.content {
	display: grid;
	grid-template-columns: 
		[full-start] minmax(1em, 1fr) 
		[main-start] minmax(0, 40em) [main-end]
		minmax(1em, 1fr) [full-end];
}

This defines the columns, including the max width of the content, and a gutter. For normal content:

CSS

.content > * {
	grid-column: main;
}

Then for items to span the full viewport:

CSS

.content__full {
	grid-column: full;
}

See the source link for more details.

Tags: 

Breaking the Grid

Dave Rupert has encountered some confusing not-actually-bugs with grid item widths in CSS Grid, and provided this as a fix:

CSS

/*
 _______  ___   _______    _______  ______    ___   ______  
|       ||   | |       |  |       ||    _ |  |   | |      | 
|    ___||   | |_     _|  |    ___||   | ||  |   | |  _    |
|   |___ |   |   |   |    |   | __ |   |_||_ |   | | | |   |
|    ___||   |   |   |    |   ||  ||    __  ||   | | |_|   |
|   |    |   |   |   |    |   |_| ||   |  | ||   | |       |
|___|    |___|   |___|    |_______||___|  |_||___| |______| 
by Dave Rupert
Read More: https://daverupert.com/2017/09/breaking-the-grid/
*/
 
/* 
 * Remove `min-width: auto` from Grid Items
 * Fixes overflow-x items.
 */
.fit-grid > * { min-width: 0; }
 
/* Apply max-width to Replaced Elements and Form controls */
.fit-grid img,
.fit-grid video,
.fit-grid audio,
.fit-grid canvas,
.fit-grid input,
.fit-grid select,
.fit-grid button,
.fit-grid progress { max-width: 100%; }
 
/* Make file and submit inputs text-wrap */
.fit-grid input[type="file"],
.fit-grid input[type="submit"] { white-space: pre-wrap; }
 
/* Fix Progress and Range Inputs */
.fit-grid progress,
.fit-grid input[type="range"] { width: 100%; }
 
/* Fix Number Inputs in Firefox */
@supports (--moz-appearance: none) {
  .fit-grid input[type="number"] { width: 100%; }
}

Tags: 

Is it really safe to start using CSS Grid Layout?

The really short version? Absolutely. Slightly longer version:

Grid is new! Surely it has terrible browser support?

CSS Grid Layout shipped into Chrome, Firefox, Opera and Safari in March of this year. Microsoft Edge currently have an updated Version of Grid available behind a flag in Preview builds. At the time of writing, Can I Use indicates a global availability of CSS Grid Layout of 65.64%, rising to 70.75% if you include the prefixed version in IE10, 11 and current Edge. This is a rate of adoption we’ve never seen before for such a huge feature. It isn’t surprising that people don’t realise how many visitors will have support.

[…]

And non-supporting browsers?

CSS has the solution for you. To start with, defined in the Grid and Flexbox specifications are exactly how those specifications overwrite older layout methods.

Therefore if you want to use floats, inline-block, multiple-column layout, flexbox or even display: table as a fallback for your grid layout then the spec has you covered. You can overwrite those methods in a safe and predictable way. I made a cheatsheet explaining the fallbacks. I also cover several of these in my talk which was recorded at Render Conference earlier this year.

CSS also has Feature Queries. These have really great browser support, and the nice thing about Feature Queries is that you don’t need to concern yourself with the browsers that don’t support feature queries. There is no browser supporting Grid Layout and not supporting Feature Queries.

[…]

Generally you will then have a few things in the fallback CSS that will “leak through” to the grid layout. This is often widths on items as we need to assign widths to items in legacy layout to fake something that looks like it is using a grid. Therefore we use a simple feature query, checking for support of Grid Layout, and there we perhaps set widths back to auto.

Tags: 

Old browsers are not your fault, but they are your responsibility

The fact old browsers exist is not your fault. Don’t start these discussions by acting as if it is your failing that you can’t get the site looking identical in all browsers released in the last 10 years, while using technology only released this year. It’s not your fault, but it is your problem. It is your problem, your responsibility as a web professional to get yourself into a position where you can take the right course of action for each project.

Tags: 

Using CSS Transitions on Auto Dimensions

We’ve all been there. You’ve got an element you want to be able to collapse and expand smoothly using CSS transitions, but its expanded size needs to be content-dependent. You’ve set transition: height 0.2s ease-out. You’ve created a collapsed CSS class that applies height: 0. You try it out, and… the height doesn’t transition. It snaps between the two sizes as if transition had never been set. After some fiddling, you figure out that this problem only happens when the height starts out or ends up as auto. Percentages, pixel values, any absolute units work as expected. But all of those require hard coding a specific height beforehand, rather than allowing it to naturally result from the size of the element content.

[…]

If you were hoping I had a magical, complete solution to this problem, I’m sorry to disappoint you. There’s no one solution that achieves the desired effect without downsides. There are, however, multiple workarounds that each come with a different set of advantages and disadvantages, and in most use cases at least one of them will get the job done in an acceptable manner. I’ll outline the major ones, and list out their ups and downs so you can hopefully pick the best one for your situation.

[…]

Technique 1: max-height

If you web search this problem, the max-height approach will probably be mentioned in all of the first five to ten results. It’s actually pretty unideal, but I thought it was worth including here for the sake of comparison.

It works like this: CSS values can only be transitioned to and from fixed unit values. But imagine we have an element whose height is set to auto, but whose max-height is set to a fixed value; say, 1000px. We can’t transition height, but we can transition max-height, since it has an explicit value. At any given moment, the actual height of the element will be the maximum of the height and the max-height. So as long as max-height’s value is greater than what auto comes out to, we can just transition max-height and achieve a version of the desired effect.

[…]

Technique 2: transform: scaleY()

[…]

Implementation works like this: we set a transition for the element’s transform property, then toggle between transform: scaleY(1) and transform: scaleY(0). These mean, respectively, “render this element at the same scale (on the y axis) that it starts out at” and “render this element at a scale of 0 (on the y axis)”. Transitioning between these two states will neatly “squish” the element to and from its natural, content-based size.

Technique 3: JavaScript

Managing a CSS transition in CSS would be ideal, but as we’re learning, sometimes it just isn’t entirely possible.

If you absolutely have to have smoothly collapsing sections, whose expanded size is completely driven by their content, and which other elements on the page will flow around as they transition, you can achieve that with some JavaScript.

The basic strategy is to manually do what the browser refuses to: calculate the full size of the element’s contents, then CSS transition the element to that explicit pixel size.

Tags: 

CSS Grid Guides on MDN

A few weeks ago I was approached by the good people over at MDN, asking if I would be interested in writing a comprehensive resource for MDN on CSS Grid Layout. A series of guides to explain the grid specification with examples - ready for Grid shipping in Firefox 52 today.

I think that MDN is the best place for references and increasingly for learning web development, therefore I was very keen to add to that material and to create a learning resource for grid. Over the last couple of weeks I have written a book-worth of words and it is all available on MDN right now.

[…]

  1. Basics concepts of grid layout
  2. Relationship to other layout methods
  3. Line-based placement
  4. Grid template areas
  5. Layout using named grid lines
  6. Auto-placement in grid layout
  7. Box alignment in grid layout
  8. Grids, logical values and writing modes
  9. CSS Grid Layout and Accessibility
  10. CSS Grid Layout and Progressive Enhancement
  11. Realizing common layouts using grids

Tags: 

Expand last row of wrapped flex items to fill entire row

Thanks to Jonathan Snook, I’ve learnt that we don’t need quantity queries to create a balanced grid. Quantity queries are very powerful, but so is Flexbox. If we just want all the items in the last row to fill the space, regardless of how many there are, then Flexbox can take care of this. But if we want to add additional styles to the items, we still need quantity queries.

This is the grid we want to achieve:

A wrapped grid of flexbox items. The first two rows have four items each, stretching to the full width of the container. The third row only has three items, but they also stretch to the available space.

Here’s the Flexbox magic.

The container needs to have the property display: flex; and the items need to be wrapped using flex-wrap: wrap;

CSS

.list {
    display: flex;
    flex-wrap: wrap;
}

Now here’s the clever bit. We can set an initial width to the items (in this case flex-basis: 23%;) so that each item will always get a width of 23% unless otherwise stated in the CSS. flex-grow: 1; tells the items to grow and fill the space in the row.

CSS

.list-item {
    ...
    flex-basis: 23%;
    flex-grow: 1;
}

So, thanks to flex-grow, no matter how many items are in the last row, they will always fill the space. Works like magic! It’s amazing how much can be achieved with so little CSS.

Tags: 

Pages