10 CSS properties you should try to use

calendar icon
29 Mar
2024
27 Dec
2022
scroll

CSS keeps actively evolving, boasting new properties and features. By learning and using them, we can simplify and expedite web development, follow modern trends and solve various problems more easily. In addition, with CSS, it is possible to create functionality that previously could only be implemented using JavaScript. This increases the reliability of applications and optimizes their performance.

This article will examine some of the relevant CSS properties mentioned in the annual State of CSS survey. This survey seeks to understand the current CSS ecosystem and inform us about the main directions it took. This year, Lea Verou, a member of the W3C working group and a person at the forefront of all the changes that are taking place, has joined in to help draft the questions for it. Probably partly due to her participation, this year’s survey focused on new and upcoming CSS features.

First of all, let’s focus on the features and capabilities that can be used today. They are well-supported by popular browsers, and their usefulness is confirmed through practice. While we’re at it, we will also cover some of the innovations that are expected in the near future.

aspect-ratio

The aspect-ratio property offers a simple, convenient and straightforward method of setting the aspect ratio for an element. It is defined as the ratio of an element’s width to its height and calculates the other side based on the size of the one already known.

The aspect-ratio property will be useful for the adaptive layout of maps, cards, videos, iframes, and other elements for which it is important to keep the aspect ratio when resizing.

Here you can see two blocks with the same aspect ratio. One is 600 x 900 pixels, and the other is 200 x 300 pixels — with both having a 2:3 aspect ratio
Here you can see two blocks with the same aspect ratio. One is 600 x 900 pixels, and the other is 200 x 300 pixels — with both having a 2:3 aspect ratio

Code example

Let’s create an element that has 100% of the width of the parent element and a width-to-height ratio of 2 to 3:

.item {
  width: 100%
  aspect-ratio: 2 / 3;}

For images and videos, it is convenient to combine the aspect-ratio property with the object-fit property, where aspect-ratio defines the aspect ratio of an element, and object-fit specifies how the content will fill it.

Previous approaches

Before the aspect-ratio property, we used the padding-top property to maintain the aspect ratio. This is possible because the padding property, expressed as a percentage, is based on the parent element’s width.

For example, in order to set the aspect ratio of the 16/9 video, we had to write the following:

.video {
width: 100%;
padding-top: 56.25%;}}

Such an entry is counterintuitive and obscure, resembling a hack rather than a basic language feature.

Compare it with how we can define such a ratio today:

.video {
width: 100%;
aspect-ratio: 16 / 9;}

The usage has become much clearer and does not require revising the padding property to implement something outside of its normal scope.

Browser support: 91.23%

Data on support for the mdn-css__properties__aspect-ratio feature across the major browsers from caniuse.com

Specification: W3C Editor’s Draft

content-visibility

The content-visibility property aims to expedite the first loading and first rendering of the web page so that you can interact with the newly rendered content immediately without waiting for the rest of the content to load.

By using the content-visibility property, developers can tell a browser which parts of a page contain isolated content. This, in turn, will allow the browser to optimize page rendering through delayed calculations.

Developers demonstrated how the content-visibility: auto property applied to partitioned content increased rendering speed by a factor of 7 — from 232 ms to 30 ms
Developers demonstrated how the content-visibility: auto property applied to partitioned content increased rendering speed by a factor of 7 — from 232 ms to 30 ms

Code example

Let’s optimize the loading of sections. The content-visibility property with the auto value ensures the maximum possible performance gain with minimal effort.The height of the section (in this case, 1000 px) must be specified so that the browser will reserve space for it.

.section {
content-visibility: auto;
contain-intrinsic-size: 1000px;}

With the content-visibility property, a browser will load and style the content that the user currently sees on the screen. For the rest of the content, it is enough to specify its height. In this case, contain-intrinsic-size acts as a placeholder.

Previous approaches

Without the content-visibility property, a browser loads and styles all parts of the page regardless of whether they are currently visible to users. When it’s applied, however, the browser will load and style only the content currently visible to the user (on the screen), treating the rest of the content as if it contained empty sections. This leads to a significant increase in rendering speed.

Browser support: 72.95%

The content-visibility property was announced in August 2020. It works in Chrome and Opera but is not supported by Safari and Firefox.

Data on support for the css-content-visibility feature across the major browsers from caniuse.com

Specification: W3C Working Draft

gap property for flexbox

The gap property in flexbox is used to set the distance between flexbox items.

To specify the same distance between rows and columns, we use the gap property with one value. If the distance between rows and columns is different, we use gap with two values, first specifying the distance between rows and then between columns. To make the code clearer and more transparent, you can use two properties: row-gap and column-gap.

We use the row-gap property to set the distance between rows, and the column-gap property sets the distance between columns
We use the row-gap property to set the distance between rows, and the column-gap property sets the distance between columns

Code example

We specify the gap property to the flex container. By using the row-gap and column-gap properties, we can set the distance between the rows and columns of the flex elements:

.item-container {
display: flex;
row-gap: 30px;
column-gap: 20px;}

The same code fragment can be made shorter:

.item-container {
display: flex;
gap: 30px 20px;}

Previous approaches

Before the property gap, the margin property was used to set distance between flex elements. The downside of this approach was that the margin property also added an indent between the element and the edge of the container.

To solve this problem, one could use various methods:

  • The :last-child pseudo-class, allowing to specify that the last element is not indented;
  • Setting a negative value for the margin property;
  • The three-character CSS selector, which is often called the “lobotomized owl selector”. It looks like this: * + *, resembling the blank stare of an owl, hence the name. This selector allows you to specify properties for an element only if it comes after another element of the same type.

In addition to their complexity and non-obviousness, all of these methods had another disadvantage — they worked only when flex elements were arranged in a single line and were not suitable for multi-line structures.

The gap property works for both single-line and multi-line arrays of flex elements, allowing you to specify the indentation between elements without resorting to such hacks and tricks, instead just relying on the basic features of the language.

Browser support: 95.42%

The gap property in flexbox was introduced quite recently in 2021 as a result of migration from a grid, but due to its simplicity and ease of use, it quickly became popular.

Data on support for the flexbox-gap feature across the major browsers from caniuse.com

Specification: W3C Editor’s Draft

object-view-box

The object-view-box property allows displaying only the specified portion of an image or video on a web page. It is somewhat similar in effect to the viewBox svg attribute.

The object-view-box property will be useful when you want to display only certain portions of an image or video for different elements or at different resolutions. It can also be used to zoom or pan images and videos.

In this example, we have an image that needs to be cropped. Note that we only need a certain part of this image
In this example, we have an image that needs to be cropped. Note that we only need a certain part of this image

Code example

Let’s assume we need to cut a square from an image, a 25% margin from the top edge, 20% from the right edge, 15% from the bottom edge, and 5% from the left edge. Code allowing us to do that would look that:

.img {
aspect-ratio: 1;
width: 300px;
object-view-box: inset(25% 20% 15% 5%);
object-fit: cover;}

The inset(25% 20% 20% 15% 5%) values indicate the top, right, bottom and left positions of the frame within the original image to be displayed. And the object-fit property with the cover value ensures that the resulting fragment will not be distorted.

Currently, we cannot animate the object-view-box property through the transition property, but it can be animated using @keyframes to obtain a smooth change in scale or viewport.

Previous approaches

Without the object-view-box property to solve the problem of cropping images or videos, we had to use a wrapper element with the overflow: hidden; property, positioning and scaling the content inside it. For images, you can also use the background-image property instead of the img tag, applying the background-position and background-size properties for positioning and scaling. Another common, though perhaps suboptimal, solution, is to use different files for different fragments of the same image.

Browser support:

The object-view-box property is totally new, being introduced in May 2022. Despite that, it is already supported by the latest versions of Google Chrome and Opera.

Specification: W3C Editor’s Draft

inset

The inset property replaces the four other properties: top, right, bottom, and left, allowing you to specify the inset of the positioned element on all four sides at once.

The inset property is like a shorthand for the margin and padding properties. It allows you to specify the inset of the positioned element from the top, right, bottom, and left.

Instead of using the top, right, bottom, and left properties, you can go with a single inset property
Instead of using the top, right, bottom, and left properties, you can go with a single inset property

Code example

This is code for a perfectly positioned pop-up modal window that takes up the entire area of the browser:

.modal {
position: absolute;
inset: 0;}

This short entry solves a common problem of stretching a completely positioned element to the full width and height of the page.

Previous approaches

Before the inset property, we would solve the problem of stretching a positioned element over the whole area of the view window like this:

.modal {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;}

It goes without saying, that using one property instead of four is convenient and compact.

Browser support: 92.12%

Data on support for the mdn-css__properties__inset feature across the major browsers from caniuse.com

Specification: W3C Editor’s Draft

scrollbar-gutter

The scrollbar-gutter property allows for reserving scrollbar space. When we use this property, the content is not rearranged depending on whether there is a scroll bar or not.

The scrollbar-gutter property is useful for developers of single-page applications filled with dynamic content. Previously, if a scroll bar appeared in such an application, all the content would shift to the left along the scrollbar width.

When the amount of content increases, a scroll bar appears on the right, with all the content sharply shifting to the left
When the amount of content increases, a scroll bar appears on the right, with all the content sharply shifting to the left
With the scrollbar-gutter property, you can reserve the scrollbar space
With the scrollbar-gutter property, you can reserve the scrollbar space

Code example

This code reserves space for the scrollbar space and ensures that the content is not displaced when it appears.

html {
scrollbar-gutter: stable both-edges;}

Previous approaches

Before the introduction of the scrollbar-gutter property, to prevent content from being shifted when the scrollbar appeared, we had to resort to a hack with a negative margin and the overflow-x: hidden property for HTML:

html {
overflow-x: hidden;
margin-right: calc(-1 * (100vw - 100%));}

Browser support: 74.6%

This property is supported by all the evergreen browsers.

Specification: W3C Editor’s Draft

text-overflow and line-clamp

The text-overflow and line-clamp properties are used to truncate text if it does not fit inside the viewport. You can use the text-overflow property if you want to trim single-line text, and the line-clamp property is useful for truncating multi-line text.

In this example, the content of the articles is cropped, with only the first two lines remaining visible — all thanks to the line-clamp CSS property
In this example, the content of the articles is cropped, with only the first two lines remaining visible — all thanks to the line-clamp CSS property

Code examples

The text-overflow property with the ellipsis value truncates one line of text to the width of the container, leaving three dots at the end:

.title {
display: block;
width: 350px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;}

The text-overflow property works only for block containers if the element is also given white-space property with a nowrap value and overflow property with a hidden, scroll, or auto value.

The available values for the text-overflow property are clip (when the text is cropped exactly at the edge of the parent block) and ellipsis (when an ellipsis is added at the end of a line).

The line-clamp property is used with the -webkit prefix. A value of 2 means that only two lines of text remain visible.

.text {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;}

The line-clamp property works only for a block container, in combination with the display and the -webkit-box-orient property. You will also need the overflow property with the hidden value to truncate the content after a specified number of lines.

Previous approaches

Truncating text to a specified number of characters can easily be done with JavaScript:

const cutText = (text, count) => {
return text.slice(0, count) + ’...’;}

Here, count means the number of characters up to which the text should be cut. This method is simple enough, but it has one disadvantage. Unlike CSS, JavaScript knows nothing about lines of text. It can truncate it by leaving a specified number of characters, but the text containing the same number of characters can take up a different number of lines. As a result, truncating text with JavaScript will be less reliable compared to CSS.

Browser support: 96,24%

The property is used with the following prefix: -webkit-line-clamp

Data on support for the css-line-clamp feature across the major browsers from caniuse.com

Specification: W3C Editor’s Draft

variable fonts

Variable fonts have a particular feature where one font file is used for any style. When it comes to a regular font, if your layout uses two styles, such as regular and bold, you need to upload two font files. For a variable font, only one file containing all the typeface variants needs to be loaded.

Variable fonts can be used just like regular ones, but in reality, they can offer much more. For regular fonts, the font-weight property takes values from 100 to 900 in increments of 100, while for variable fonts, it can be any integer between 1 and 999. For normal fonts, the font-style property takes two normal and italic values, whereas for variable fonts, you can specify the oblique angle from –90deg to 90deg. The font-stretch property of variable fonts varies from 50% (narrow typeface) to 200% (wide typeface), where the normal proportion corresponds to 100%. And then there’s the font-optical-sizing property, which changes the appearance of a font depending on its size.

Different typefaces of static fonts are stored in separate files, however, when it comes to variable fonts, a single file is enough
Different typefaces of static fonts are stored in separate files, however, when it comes to variable fonts, a single file is enough

Code example

Code for loading a variable font:

@font-face {
font-family: Inter;
src: url("assets/fonts/Inter.woff2");}

Inter is one such variable font, and it is enough to load one font file for all typefaces.

Previous approaches

Code for loading a static font:

@font-face {
font-family: Roboto;
src: url("assets/fonts/RobotoThin.woff2");
font-weight: 100;
}
@font-face {
font-family: Roboto;
src: url("assets/fonts/RobotoRegular.woff2");
font-weight: 400;}

Roboto is a static font, and for each typeface, we have to load a separate font file.

Browser support: 95,95%

The variable fonts were first introduced at the end of 2016 and can boast excellent browser support.

Data on support for the variable-fonts feature across the major browsers from caniuse.com

Specification: W3C Editor’s Draft

CSS custom properties (variables)

CSS variables are CSS properties with specified values that are declared by the code author so that they can be reused in a document. They also help avoid code duplication. You can define a variable only once and then reuse it in code as necessary. If you want to make a change, you only have to modify the value of a variable in one place.

CSS variables can be managed from JavaScript.

Getting a value of the CSS variable:

element.style.getPropertyValue(’--main-color’);

Setting a value of the CSS variable:

element.style.setProperty(’--translate’, `${currentScroll}px`);

They make adding transitions between dark and light themes to apps very easy and convenient.

CSS variables can be defined either in the :root element (variables will be available throughout the application) or within any selector (they will be available only for the selected element and its children).
CSS variables can be defined either in the :root element (variables will be available throughout the application) or within any selector (they will be available only for the selected element and its children).

Code example

Declaring a variable:

:root {
--color-red: #79142B;}

How to get a CSS variable value:

.item {
color: var(--color-red);}

Previous approaches

Variables first appeared in CSS frameworks. Their addition to regular CSS was a significant improvement, making it possible to optimize code, increase its readability, and provide greater flexibility.

Browser support: 96,7%

CSS variables were proposed in 2017. Currently, they are in the W3C’s candidate recommendation (CR) stage, i.e., they are the closest to actual implementation among the other features described in this article. Supported by all the popular browsers.

Data on support for the css-variables feature across the major browsers from caniuse.com

Specification: W3C Candidate Recommendation

min(), max(), clamp() CSS functions

The min(), max(), and clamp() CSS functions make up a group of comparison functions. They take several values and return one of them. The min() function returns the minimum of the values, while the max() function returns, you guessed it, the maximum one. The clamp() function takes three values: minimum, recommended, and maximum, and returns the recommended value if it is within the specified limits.

These comparison functions can expand our ability to create dynamic layouts and design flexible components. You can use them to adjust element sizes, fonts, indents, and more. Even though we could already specify minimum and maximum values for an element’s width and height, it’s the comparison functions that made it possible to do the same for font size and indentation.

The top example shows how pages are designed today, by specifying different values for various screen resolutions. At the bottom is what we can expect in the future thanks to the comparison functions.
The top example shows how pages are designed today, by specifying different values for various screen resolutions. At the bottom is what we can expect in the future thanks to the comparison functions.

Code examples and previous approaches

There’s a common task — to create a container element that stretches across the entire width of the parent, limiting its maximum size. The traditional solution looks as follows:

.container {
width: 100%;
max-width: 1024px;}

And here’s a one-line solution with the help of the min() function:

.container {
width: min(100%, 1024px);}

Here’s another real challenge — to create a 100vh high section while specifying its minimum height:

.section {
height: 100vh;
min-height: 680px;}

And here’s a one-line solution with the max() function:

.section {
height: max(100vh, 680px);}

Note that for min() and max() functions, the order of the arguments does not matter. In any case, the former returns a smaller value, and the latter returns a larger one. The same cannot be said for the clamp() function, where values must go from lesser to greater:

.design {
width: clamp(350px, 50%, 650px);}

We have a design element that takes up half the width of the parent element, but its width cannot be less than 350 px or more than 650 px.

Before the clamp() function, we would usually solve this using media queries, having specified different element widths for different screen resolutions. With the clamp() function, the task has become much simpler, and the change in element size is continuous within a specified range of values.

Browser support: 94,44%

Support for comparison functions arrived in 2020, and they work in all the popular browsers.

Data on support for the css-math-functions feature across the major browsers from caniuse.com

Specification: W3C Editor’s Draft

Conclusion

CSS is considered to be one of the simplest and yet one of the most complex languages at the same time. It’s simple enough in the beginning — you define the style properties and their values for specific elements, and that’s pretty much all you need to know!

However, CSS is constantly being updated; the approaches are changing, and new features and functionalities are introduced to find new solutions for old problems. This requires developers to be constantly aware of current changes and to improve and evolve.

I hope that the properties and capabilities described in this article were of interest to you and will be useful in your work.

Writing team:
Dmуtro
Editor
Have a project
in your mind?
Let’s communicate.
Get expert estimation
Get expert estimation
expert postexpert photo

Frequently Asked Questions

No items found.
copy iconcopy icon

Ready to discuss
your project with us?

Please, enter a valid email
By sending this form I confirm that I have read and accept the Privacy Policy

Thank you!
We will contact you ASAP!

error imageclose icon
Hmm...something went wrong. Please try again 🙏
SEND AGAIN
SEND AGAIN
error icon
clutch icon

Our clients say

The site developed by Halo Lab projected a very premium experience, successfully delivering the client’s messaging to customers. Despite external challenges, the team’s performance was exceptional.
Aaron Nwabuoku avatar
Aaron Nwabuoku
Founder, ChatKitty
Thanks to Halo Lab's work, the client scored 95 points on the PageSpeed insights test and increased their CR by 7.5%. They frequently communicated via Slack and Google Meet, ensuring an effective workflow.
Viktor Rovkach avatar
Viktor Rovkach
Brand Manager at felyx
The client is thrilled with the new site and excited to deploy it soon. Halo Lab manages tasks well and communicates regularly to ensure both sides are always on the same page and all of the client’s needs are addressed promptly.
Rahil Sachak Patwa avatar
Rahil Sachak Patwa
Founder, TutorChase

Join Halo Lab’s newsletter!

Get weekly updates on the newest stories, posts and case studies right in your mailbox.

Thank you for subscribing!
Please, enter a valid email
Thank you for subscribing!
Hmm...something went wrong.