Skip to main content

10 amazing new CSS techniques

This is a very exciting time to be a web developer. We will take a look at some of the new CSS properties and entire specifications that are making their way into browsers. Some of these are behind flags or only available in beta versions of browsers now but you will be seeing them in release versions very soon.

Gutters for Flexbox

Browsers implementing the gap properties for Flexbox will mean an end to using margins and negative margins to make gutters

Browsers implementing the gap properties for Flexbox will mean an end to using margins and negative margins to make gutters

CSS Grid Layout introduced the grid-column-gap, grid-row-gap and grid-gap properties. Multi-column layout already had column-gap. It therefore made sense to remove these properties from the Grid and Multicol specifications and place them into Box Alignment, the specification that deals with space distribution and alignment across all specifications. This meant the gap properties – now renamed column-gap, row-gap and gap for all contexts could be specified for other layout methods – such as Flexbox.

At the time of writing, Firefox is the only browser to have implemented these properties for Flexbox and they are expected to ship in Firefox 63 (which should be available by the time you read this). However I would expect other browsers to follow suit. This should mean that instead of having to use margins to create gutters between flex items, you'll be able to use gaps as in grid layout.

.flex {
  display: flex;
  flex-wrap: wrap;
  row-gap: 20px;
  column-gap: 10px;
}

Logical properties and values

Using the logical sizes block-size and inline-size instead of width and height the box rotates to match the writing direction

Using the logical sizes block-size and inline-size instead of width and height the box rotates to match the writing direction

Our CSS properties and values have traditionally been mapped to the physical properties of a screen. For example, we use width and height and we set margins on the top, right, bottom and left of an element. These physical properties seem strange when working in writing modes other than horizontal and top to bottom. As a simple example we can think about a box with both a height and a width.

.box {
    height: 150px;
    width: 250px;
}

Our box will be 150 pixels tall on the screen and 250 pixels wide. Even if we change the writing mode to a vertical one, the box will remain tied to its physical dimensions.

We now have new logical properties and values that enable us to size elements or refer to their margins, padding and borders in such a way that makes sense even if the writing mode changes. If we return to our previous example, we might want our box to always have a length of 250 pixels in the inline dimension regardless of orientation.

The inline dimension is the way that a sentence runs in that writing mode – so horizontally in English, and vertically in any vertical writing mode. We then want it to have a length of 150 pixels in the block dimension, which is the way that blocks such as paragraphs are displayed in that particular writing mode. So we could size our block as follows:

.box {
    block-size: 150px;
    inline-size: 250px;
}

The box now follows the writing mode in use. There are logical properties and values being created and implemented in values for every physical counterpart: Firefox currently has the best support for these.

Grid level 2 and subgrid

Work is already underway of Level 2 of the CSS Grid Layout specification. This level is all about the subgrid feature. Subgrids will mean that in addition to the direct children of a grid container becoming a grid item, you will be able to create a grid on a grid item and have it use the column and row tracks of the parent. This would mean, for example, that you could create a multiple column grid for your page and use that to line up items nested in the markup.

.grid {
    display: grid;
    grid-template-columns: 1fr 2fr 1fr 2fr;
}

.item {
    grid-column: 2 / 5;
    display: grid;
    grid-template-columns: subgrid;
}

In the above CSS example, I have a parent element set to display: grid, which defines a four-column grid. The child item with a class of item is placed on the grid from column line 2 to column line 5, spanning three tracks of the parent grid. By using the value subgrid in place of a track listing for grid-template-columns on the child item, we tell its grid to use the tracks from the parent. Any child of item will therefore use the sizing of column tracks as defined on the parent grid.

This is not yet implemented in any browser, however I expect we should start to see implementations soon.

Initial letter

A fancy initial letter can be inset into our content with the initial-letter property, which is currently only available in Safari

A fancy initial letter can be inset into our content with the initial-letter property, which is currently only available in Safari

Initial Letter, currently only implemented in WebKit, is a little feature that solves a common problem. It enables the creation of a large initial letter (or drop capital) sunk into the text that follows it.

The CSS is one property: initial-letter; to see it working you need the prefixed WebKit property for Safari and iOS Safari. The two values for initial-letter are the number of lines the letter should span in height and then the number of lines it is to be indented into the text.

h1+p::first-letter {
  font-weight: bold;
  -webkit-initial-letter: 4 3;
  initial-letter: 4 3;
}

Variable fonts

Play with the capabilities of variable fonts using the Axis Praxis website, and find fonts which support the new features

Play with the capabilities of variable fonts using the Axis Praxis website, and find fonts which support the new features

If you have ever used a web font in a design, you will understand the problem of needing to include – and therefore your user needing to download – each variant of the font that you need to use. For most fonts, you will want the regular, bold and the italic versions of the font. That's four requests plus a reasonable amount of data to download.

A variable font is a single font file that contains all of the above variants and many more. OpenType Font Variations is technology jointly developed by Microsoft, Google, Apple and Adobe and this feature should make using beautiful typography on the web much easier.

To utilise variable fonts you need to use a font that supports the feature, and a browser that has implemented the font-variation-settings property, which enables you to control the various axes of your chosen font. Support in modern browsers is excellent. To get a feel for how controllable fonts can be, check out the Axis Praxis website, where you can play with various fonts and copy out the CSS used for the font variant that you have created.

To find and test variable fonts, visit v-fonts.com. The Variable Fonts Twitter account is worth following to discover new font releases and other news.

Scroll snapping

Our scroll snap example snaps each item to the start as the visitor scrolls a box with overflow: scroll vertically

Our scroll snap example snaps each item to the start as the visitor scrolls a box with overflow: scroll vertically

CSS Scroll Snapping means that you can create interfaces that snap to scroll points. This is useful for full-page interfaces that you want to act in a similar way a mobile app might, snapping from page to page. 

The code below creates a list of items, where the parent has a fixed height and the overflow is set to scroll. I want the items to snap to the top of the container as they are scrolled to.

On the parent element we add the property scroll-snap-type, which has a value of the axis that we are scrolling on and then a keyword of mandatory or proximity. The mandatory keyword will force snapping to the snap point, therefore you should be careful when using this that you don't cause a situation where the user is unable to scroll to some of the content because of the scroll snapping.

On the items we specify where we want to snap to using the property scroll-snap-align. In this case I have selected start; the other values are center and end.

ul {
  list-style: none;
  border: 5px solid rgb(126,63,222);
  border-radius: .5em;
  height: 300px;
  padding: 0;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  
}

li {
  background-color: rgba(126,63,222,.3);
  padding: 40px 20px ;
  border-bottom: 1px solid rgb(126,63,222);
  min-height: 150px;
  scroll-snap-align: start;
}

Media Queries Level 4

The Media Queries Level 4 specification gives us some interesting new ways to detect the device a visitor is using, plus some syntax improvements that help to make Media Queries less verbose.

Detect pointer type

The ways in which people interact with your site or application are changing. Your visitor might be visiting your site on a touchscreen-enabled device, using a keyboard and mouse or – with devices such as the Microsoft Surface Book acting like traditional laptops that also have a touchscreen – both at once. Therefore, looking at screen size isn't a good way to find out what type of device your user actually has. Media Queries Level 4 introduces Interaction Media Features, which enable us to find out what type of pointer a user has, and test for properties such as the ability to hover.

For example, if I wanted to add some CSS for touchscreen users, I could use the following code to test for a coarse pointer:

@media (pointer:coarse) {
    /* CSS rules for touch screen */
}

I could also test for the ability to hover: 

@media (hover) {
    /* CSS rules useful to people with devices that have hover support */
}

These Media Queries give you another way to test for device capabilities in order to give a great experience to all visitors to your site. They are currently supported in all modern browsers other than Firefox.

Syntax improvements for Media Queries

The Level 4 specification also includes some syntax improvements as Media Queries currently are very verbose – in particular when specifying a range, for example:

@media (min-width: 40em) and (max-width: 59em) {
	/* CSS rules for screen sizes between 40em and 59em */
}

The new specification enables us to use the following syntax and achieve the same thing:

@media (40em <= width <= 59em ) {
	/* CSS rules for screen sizes between 40em and 59em */
}

This syntax looks strange at first but what we are saying is that the width should be greater than or equal to 40em, and also less than or equal to 59em. It may be helpful to look at the width first then compare it to the things on either side. The old syntax isn't going away so you can use either.

Use CSS to test browser support

Feature Queries have excellent browser support, test-for support, and anything new in CSS&nbsp;can be tested for using them

Feature Queries have excellent browser support, test-for support, and anything new in CSS can be tested for using them

CSS has even developed a way for you to test for browser support of new CSS features, with Feature Queries. A Feature Query behaves in much the same way as a Media Query, except that instead of asking the browser something about the device being used to view the site, a Feature Query asks the browser if it supports a particular CSS feature. This makes it easier to use new features in a safe, progressively enhanced way.

@supports (display: grid) {
	/* CSS rules for browsers that support grid layout */
}

Browser support for Feature Queries is great, however they are not supported in Internet Explorer 11 and below. This is less of a problem than you might think: as long as you test for support and then write the code for supporting browsers, you can overwrite anything you needed to previously do in your CSS for those older browsers. Anything new that comes into CSS you can use Feature Queries to test for. I think they are one of the best things to come into CSS recently because they enable us to start using new features more quickly and, as you've seen in this article, there is a lot to get started with! 

This article originally appeared in net magazine issue 312. Buy it here.

Read more: