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.

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%
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.

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.
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.

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.
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.

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.

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%
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.


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.

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
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.

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.
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.
.avif)

.avif)