Starting to write CSS in 2023 will be different

w3cplus
57 min readJan 5, 2024

--

CSS is evolving faster than ever. After Flexbox and Grid , CSS seems to have gone through a long period of stagnation, but in recent years, CSS has added many new features available , and there will be more new features coming soon. This development speed is exciting, but also overwhelming.

Although CSS has added many new features , many web developers believe that these fancy things have not brought substantial changes to themselves. In other words, have all these fancy things (CSS new features) actually changed the way you write CSS? For most web developers, the new features of CSS have indeed influenced the way CSS is written today, but perhaps not as thoroughly as I expected.

Although I have seen many blog posts as well as introductions and examples of these trendy things in my own booklet “ Modern CSS “, I have not yet seen these practical applications used in production or daily life. This is not a complaint about anyone or anything. Personally, I am very excited about the evolution of CSS. Many of the latest features are what we have been longing for for years. Indeed, some of these features are gradually being incorporated into my CSS. Although not a complete change, it is enough to make me enjoy writing CSS more than ever.

2023 is an important year for CSS!

From the 2023 Google I/O conference at the beginning of the year to the WWDC23 conference at the end of the year, as well as @Bramus’ sharing at the @Frontmania conference in Utrecht and the recent “ CSS Wrapped: 2023! “ shared by Chrome team, they are all talking about the latest features of CSS. I am no exception I spent half a year explaining modern features of CSS in the form of a booklet Fortunately, the latest features of CSS introduced in my booklet Basically (more than 95% of the features) have appeared in the topics of these conferences.

Brochure address: https://juejin.cn/book/7223230325122400288

It can be said that there are always dozens of new CSS features supported by mainstream web platforms. It can be said that 2023 is a very important year for CSS. These developments have made features that developers once thought were impossible to achieve on web platforms a reality. Nowadays, mainstream modern web browsers support CSS container queries ( size queries , style queries and status queries , etc.), subgrids ( subgrid ), relational selectors : has () (also often referred to as parent selectors), complex n- * selectors, and a series of new color spaces and functions , such as color () and color-mix () . Chrome browser also supports scroll-driven animations implemented with CSS only, as well as view transition effects that smoothly transition between web views (if you are interested in web animations, you can read " Web Animation Journey "). Most importantly, many new basic features have emerged, such as CSS layers ( @layer ) , nesting and scopes , etc., which can better improve the experience of web developers writing CSS, and even change the way web developers write, maintain and manage CSS.

It’s been a wonderful year! Seeing so many new features, are you a little hesitant? There are so many new things in CSS? It may even confuse you, is this still the CSS you know?

Ask yourself how much you know and how much you have used. What’s more important is whether these new features have really brought changes to you!

Give up your hesitation

Under normal circumstances, people’s behavior towards new things varies due to Individual Differences. Some people may show curiosity, excitement, and positivity, while others may show fear and resistance. Similarly, when web developers face new features of CSS, they may also show various reactions and behaviors, which depend on their technical level, project requirements, personal preferences, and acceptance of new technologies. For example, some colleagues may be curious and excited about new features of CSS (like me). For these colleagues, they will immediately take action to learn and practice these new features, and even actively participate in community building to make these new features more perfect. Of course, there are also some colleagues who will show resistance, conservatism, or even rejection. Moreover, in the Chinese community, this group of people accounts for the majority because I often hear my friends around me hesitate about new features. Can these fancy things be used? Is compatibility good? And so on!

Here, what I want to say is that new features will continue to evolve and improve over time. Just like when promoting CSS3 features, the most frequently asked question was “Are new features compatible with IE?”

Nowadays, I am also asked similar questions: “How compatible are these new features?” At the same time, many colleagues ask me how and where to obtain these new features. In fact, this is a good thing, which means that more colleagues are giving up hesitation, fear, and rejection of new features.

This is already a change.

In fact, the current environment is friendly to web developers, and we can obtain version release information for new features, compatibility data, interoperability, and information provided by the web platform in different ways.

Version release

We can get new features and bug fixes introduced by various Web platforms in the release of mainstream browsers such as Chrome , Safari and Firefox .

Release notes

Web platforms ( Chrome , Safari , and Firefox ) provide documentation with detailed information about new features, improvements, and bug fixes each time a new version is released. Web developers can learn about relevant information by reading the release notes. Similarly, we can also obtain CSS-related information in the corresponding documentation, including the latest features, feature improvements, and bug fixes.

Compatibility data

The key factor for web development to stop new CSS features is cross-platform compatibility. If you want to know the compatibility data of a new feature, you can get it through platforms such as Can I Use , Browser Compat Data and Time to Stable .

Interoperability

Interop is a cross-browser effort aimed at improving the interoperability of the Web. Interoperability refers to the effort to improve the interoperability of Web technologies in different browsers. Interoperability refers to ensuring consistent behavior and effects when using the same Web technology in different environments (especially different browsers). Simply put, each technology achieves exactly the same state in all browsers.

Interop started in 2021, and modern browsers have all participated. So far, there are Interop2021 , Interop2022 and Interop2023 :

From the above picture, you can see the efforts made by various web platforms for CSS in 2023, which is why so many new CSS features will be supported by mainstream web browsers in 2023.

Platform News

In web.dev blog , you will get the latest news about the Web platform every month. This may include information about updates, improvements or changes in Web technologies:

As shown in the above figure, it states the new features on the web platform in December 2023.

Baseline

The benchmark was introduced at the 2023 Google I/O conference to clarify whether web platform features are available for use. The original definition of Baseline is that when current and previous versions of all major browsers (Chrome, Edge, Firefox, and Safari) support these features, these features are included in Baseline.

Baseline is coming to caniuse.com soon! This blog post will introduce this integration and explore some of the features included in Baseline 2023. According to the new definition of benchmark , the feature lifecycle is divided into two stages. The first option is newly launched , and then fully launched after 30 months. If a feature is interoperable in the following browsers, it will become part of the new features provided by Baseline:

  • Safari (macOS and iOS)
  • Firefox (Desktop and Android)
  • Chrome (Desktop and Android)
  • Edge (desktop device)

In the future, when you caniuse.com check compatibility data, you will see a flag informing you whether the corresponding function is widely available in Baseline. In other words, if you see this flag, you can use it boldly without worrying about cross-browser compatibility issues. This also solves your biggest doubt about CSS new features — compatibility:

By using the resources mentioned above, you will obtain first-hand information about the Web platform and the latest information related to CSS. If you are interested in CSS or Web platform-related technologies, please subscribe to them to ensure that you always have the latest information across platforms. This will help you master more skills.

Please note the emoji before the CSS feature title introduced next, which represents the new Baseline badge! Click here for details:

  • 💯: Added all stable versions of major browsers (use with confidence)
  • 👁️: Major browsers only support some features (have to wait)

Architecture foundation

Let’s start with the core functions of CSS. These are the fundamental features that play a fundamental role in how you write and organize CSS. These fundamental features solve the problems that have always been a headache for web developers in CSS. It can be said that these features will directly change the way you write, manage, and maintain CSS code.

💯 cascade layer

Cascading layers are the most important concept in CSS. Many web developers fear them, one of the reasons being that the CSS they write can easily cause conflicts or be overwritten. For example:

ul[class] { /* (0,1,1) */
margin: 0;
padding: 0;
list-style-type: none;
}
.nav { /* (0,1,0) */
margin: 0 40px; /* 被 ul[class] 中的 margin 覆盖 */
}

To determine which declaration (CSS style rule) will “win” (and be applied to elements), cascading provides corresponding algorithms. Understanding cascading algorithms helps us understand how browsers resolve style rule conflicts, that is, browsers decide which style rule to apply to elements. However, it should be noted that cascading algorithms have different descriptions in different specifications, and six different levels are provided in Level 5. Without considering cascading layers, their standards are as follows:

As in the example above, we need to increase the .nav weight according to this criterion:

ul[class] { /* (0,1,1) */
margin: 0;
padding: 0;
list-style-type: none;
}
ul.nav { /* (0,1,1) */
margin: 0 40px;
}

Colleagues familiar with CSS should know that the priority of these standards is arranged from high to low, and check them one by one until a obtained declaration is determined. If it cannot be determined which attribute declaration will win at the higher standard, the cascade will move to the next standard. For example, as shown in the figure below.

To solve problems such as cascading and weights, CSS adds a cascading layer rule, @layer .

Simply put: Cascading layers provide a structured way to organize and balance CSS rules in a single source that ultimately determines who wins !.

Due to the unique position of the cascading layer in CSS cascading, using it has some benefits, allowing developers to have more control over the cascading. The cascading layer of CSS is generally located between the “Style Attribute” and the CSS selector weight (Specificity), namely:

With @layer , we can transform the code shown earlier like this:

@layer reset, components;
@layer reset {
ul[class] {
margin: 0;
padding: 0;
list-style-type: none;
}
}
@layer components {
.nav {
margin: 0 40px;
}
}

I use the following diagram to illustrate the differences in CSS cascading before and after @layer :

The direct change brought about is that the weight calculation rules have changed.

With the CSS cascading layer @layer feature, you can abandon some of the previous CSS methodologies (such as ITCSS), because @layer can better help you manage CSS cascades.

Simply put, cascading layers @layer is a new feature of CSS that affects the application and priority of style rules. Here are some key details about cascading layers:

  • Add to Cascade Layer: Styles can be added to a specified cascade layer using the @layer rule. This allows developers to organize styles more orderly.
  • Anonymous Cascade Layer: If the @layer rule is not used, the style will be placed into the default anonymous cascade layer. This ensures that styles that do not specify a cascade layer will not affect the styles of the specified cascade layer.
  • Predefined cascading layer order: Cascading layers can predefine an order to ensure that styles are applied according to the default predefined cascading layer order when cascading layers are not explicitly specified in style rules.
  • Load external CSS files to the cascade layer: You can load external CSS files into the specified cascade layer through the @layer rule, which can organize and load styles more flexibly.
  • Cascade-less styles: You can use the @layer unlayered rule to add styles to the style layer of a cascade-less layer, and such styles are not inherited by any cascade layer by default.
  • Cascade layer nesting: You can nest one cascade layer within another to create a more complex style hierarchy.
  • Rollback Cascade Layer: You can use the @layer rule to roll back to the previous cascade layer state to undo certain style changes.

Cascading layers provide developers with the ability to manage and organize styles more finely, making it easier to maintain and extend styles in large projects.

For a more detailed introduction to the CSS cascading layer @layer feature, please read the CSS Layering: @layer course in Modern CSS !

💯 nesting

Usually, if web developers do not use CSS processors such as Sass (or SCSS), LESS, and Stylus, each CSS selector needs to be explicitly declared and separated from each other. For example:

table.colortable td {
text-align: center;
}
table.colortable td .c {
text-transform: uppercase;
}

table.colortable td:first-child,
table.colortable td:first-child + td {
border: 1px solid black;
}
table.colortable th {
text-align: center;
background: black;
color: white;
}

This will make the style code repetitive, redundant, and scattered. Therefore, many web developers will use nested methods to write CSS selectors based on the characteristics of CSS processors. For example, if the above code is written using the nested syntax of SCSS, it will look like this:

table.colortable {
td {
text-align: center;
.c {
text-transform: uppercase;
}
&:first-child {
border: 1px solid black;
+ td {
border: 1px solid black;
}
}
}
th {
text-align: center;
background: black;
color: white;
}
}

Now, CSS also has nested features similar to SCSS, and relevant style rules can be grouped into selectors to continue creating selectors.

table.colortable {
& td {
text-align: center;
.c {
text-transform: uppercase;
}
&:first-child,
&:first-child + td {
border: 1px solid black;
}
}
& th {
text-align: center;
background: black;
color: white;
}
}

Nesting can reduce the size of stylesheets, reduce the overhead of duplicate selectors, and centralize component styles. There was a limitation when this syntax was originally released: “ Any selector of CSS can be nested into another selector, but it must start with & , . (class name), # (ID), @ ( @ rule), : , :: , * , + , ~ , > or [ symbols. " These symbols are identifiers that signal to the parser that it is using nested styles. Later, with nested loose syntax updates, this limitation has been resolved, such as not needing to add & identifiers before element selectors:

table.colortable {
td {
text-align: center;
.c {
text-transform: uppercase;
}
&:first-child,
&:first-child + td {
border: 1px solid black;
}
}
th {
text-align: center;
background: black;
color: white;
}
}

Similarly, it can be nested with @ rules, for example:

h1 {
font-size: 2em;

@media (width >= 40em) {
& {
font-size: 4em;
}
}
}
/* 宽松语法 */
h1 {
font-size: 2em;

@media (width >= 40em) {
font-size: 4em;
}
}

For a more detailed introduction to CSS nesting features, please read the course “ Nesting and Scope of CSS: & and @scope “ in “ Modern CSS “!

👁️ scope

As we all know, CSS language is different from other programming languages in that it does not have the concept of scope. Usually, developers need to achieve scope-like functions through DOM structure and selectors. This makes web developers find themselves alternating between two worlds when writing selectors. On the one hand, web developers need to be clear about which elements to choose specifically; on the other hand, web developers hope that selectors will be kept later than replacement, rather than tightly coupled with DOM structure. This is also one of the reasons why tailwindcss is popular.

To this end, the W3C CSS Working Group added the @scope feature to CSS, which was first supported by Chrome (version 118). @scope is an @ rule with two main selling points: proximity-based styling and setting a lower limit for selectors . In other words, scope brings two key things to CSS:

  • One set of styles can override another set of styles based on their proximity in the DOM
  • More control over which elements selectors target (i.e. better manipulation of CSS cascades)

This means that the @scope rule lets you scope selectors to a specific subtree of the document. With the scope style, you can select elements very specifically without having to write overly specific selectors or tightly couple them to the DOM structure.

/* 根作用域 */ 
@scope (.card) {
img {
border-color: green;
}
}

Scoped style rules img { … } can actually only select < img > elements within the scope of the matched .card element. To prevent < img > elements within the card content area ( .card__content ) from being selected, you can use a more specific img selector. Another way is to take advantage of the fact that the @scope at rule also accepts range restrictions to determine the lower bound.

@scope (.card) to (.card__content) {
img {
border-color: green;
}
}

This range-bound style rule targets only < img > elements in the ancestor tree between .card and .card__content elements. Such ranges with upper and lower boundaries are often referred to as "donut ranges".

In the following example, the < img > element in the carousel component does not match due to scope restrictions:

Demo address: https://codepen.io/web-dot-dev/pen/YzBLdjG

Within the CSS cascade , @scope also adds a new condition: determine adjacent regions . This step comes after specificity but before the rendering order.

By specification : “When comparing declarations that appear in style rules with different range roots, the declaration with the fewest algebraic or sibling element hops between the range root and the style rule subject that qualifies the range wins”.

For a more detailed introduction to CSS nesting features, please read the course “ Nesting and Scope in CSS: & and @scope “ in “ Modern CSS “, or see “ How to Use @scope to restrict the coverage of selectors “ and @Miriam Suzanne’s “ CSS @scope “.

💯 selectors: is () and: where ()

:is() and :where() are two pseudo-class selectors that can be used to select a collection of multiple simple selectors and select them as a whole to simplify and optimize the writing of selectors.

  • The :is() function takes a list of simple selectors and returns an element that matches any of them, similar to | | (logical OR) in an array.
  • The :where() function also accepts a list of multiple simple selectors, grouping the elements of the selectors together to make it easier to read and use.

:is() and :where() selectors are tolerant selectors. When using :is() or :where() , if one selector cannot be resolved, the entire selector list will not be considered invalid, but will ignore incorrect or unsupported selectors and use other selectors. In addition, their usage is basically similar, the only difference is that the :where() selector weight is always 0 , while the :is() selector weight count is equal to the value of the highest weight in the selector list .

Because :where() and :is() selectors can be used to change selector weights, they can be used as a simple alternative to cascading layers. For example, if you are creating a framework or library, you can use the :where() pseudo-class function to reduce the selector weight in the framework or library to 0 . The benefit of doing this is that web developers using your framework or library do not need to deal with selector weights, and it can easily override the style rules in your framework or library.

Simply put, :is() and :where() can help us better manage CSS selector weights. The most effective way to use them is:

  • When building a CSS framework or library, use :where() to manage the weight of all selectors, reducing the selector weight to 0
  • When using boxes or libraries, you can use :is() to increase the selector weight, and without changing the HTML code, the selector weight can be increased to the highest level

Given the difference between :is() and :where() , which selector to use ultimately depends on your specific needs.

For a more detailed introduction to CSS nesting features, please read the course “ CSS Selectors: : where () vs. .: is () “ in “ Modern CSS “!

💯 selector: has ()

CSS’s :has() selector is known as the parent selector of CSS! It, like the container query feature of CSS, has always been the most wanted CSS feature for web developers.

Personally, CSS :has() is the closest to the if... else... function. It is closely related to HTML's DOM, which is the main reason why it is called a relational selector. For example, in the following example, you are looking for the existence of a descendant element, but the applied style will be the parent element.

<!-- Case ① -->
<figure>
<figcaption>CSS Pseudo-Class Specification</figcaption>
<img src="https://picsum.photos/1240/?random=11" alt="">
</figure>
<!-- Case ② -->
<figure>
<div class="media">
<img src="https://picsum.photos/1240/?random=12" alt="">
</div>
<figcaption>CSS Pseudo-Class Specification</figcaption>
</figure>
<!-- Case ③ -->
<figure>
<img src="https://picsum.photos/1240/?random=13" alt="">
<figcaption>CSS Pseudo-Class Specification</figcaption>
</figure>

The DOM trees corresponding to these three cases are shown in the following figure.

Add the following CSS code:

/* 匹配包含<figcaption>后代元素的<figure>元素 */ 
figure:has(figcaption) {
background-color: #3f51b5;
}

figure:has(figcaption) will match all figures because figures contain the figcaption element:

Demo address: https://codepen.io/airen/full/jOeMapz

What you saw above is just the simplest use of :has() , which can help you do more complex things, even some operations with interactive behavior. For example, in the following example, using :has() selector and state selector, you can implement a pure CSS-made rating component (StarRating):

Demo address: https://codepen.io/airen/full/poxeoeE

That’s why in Defensive CSS Insights , :has() is included in the category of conditional CSS , because it allows you to use different CSS based on relevant dynamic conditions in many cases.

The :has() selector is powerful. In addition to allowing us to implement some challenging GUIs without using JavaScript scripts (such as the example above), it has many other functions. For example, @wesbos recently shared a picture on Twitter , introducing ten tips for the :has() selector:

Image source: https://twitter.com/wesbos/status/1737148340322652632

For more information about the :has() selector, you can also refer to:

💯 complex n- * choice

New in CSS selector level 4 is the option to pass selector lists to :nth-child() and :nth-last-child() .

:nth-child(An+B [of S]?)
:nth-last-child(An+B [of S]?)

After specifying of S , the An + B logic applies only to elements that match the given selector list S . This actually means that you can pre-filter subitems before An + B performs the operation.

With the help of :nth-child() pseudo-class selector , we can select elements in the DOM by index. You can use An + B micro-grammar to precisely control which elements to select.

By default, the :nth- *() pseudocode considers all child elements. Starting from Chrome 111, you can optionally pass the selector list to :nth-child() and :nth-last-child() . This allows you to pre-filter the list of child items before An + B performs the operation.

In the demonstration below, the 3n + 1 logic is applied only to small dolls by pre-filtering them using of.small. Use the drop-down menu to dynamically change the selector used.

Demo address: https://codepen.io/web-dot-dev/full/YzBLdLW

What’s more interesting is that we can use :has() , :not() , ~ and + together to simulate :nth-child(An + B [of S]?) and :nth-last-child(An + B [of S]?) selectors, or even selectors that don't exist in CSS:

  • :first-in-ElementGroups-of-class(.😍) , which selects the first element in the ElementGroups (class name .😍 ), and the corresponding selector is .😍: not(: has (+ .😍)) .
  • :last-in-ElementGroups-of-class (.😍) , which selects the last element in the ElementGroups (class name .😍 ), and the corresponding selector is .😍:not(:has (+ .😍)) .
  • :single-in-ElementGroups-of-class(.😍) , which selects the only element in the ElementGroups (class name .😍 ), and the corresponding selector is .😍:not (.😍 +.😍):not(:has (+.😍)) .
  • :nth-in-ElementGroups-of-class (.😍) selects the nth element (class name .😍 ) in the ElementGroups . For example .😍:not(.😍 + .😍) + .😍 selects the 2nd element (class name .😍 ); 😍:not(.😍 + .😍) + .😍 + .😍 selects the 3rd element (class name .😍 ).
  • :nth-last-in-island-of-class (.special) selects the nth last element (class name .😍 ) in the ElementGroups . For example , .😍:not(:has(+.😍 +.😍)):has(+.😍) selects the 2nd last element (class name .😍 ), .😍:not(:has (+.😍 +.😍 +.😍)):has(+.😍 +.😍) selects the 3rd last element (class name .😍 ).

Demo address: https://codepen.io/airen/full/rNqmGrN

💯 CSS trigonometric function

The CSS Values and Units Module Level 4 in the W3C specification provides web developers with mathematical expression -related capabilities. In addition to the familiar calc() function and CSS comparison function (such as min() , max() and clamp() ), there are also CSS triangle functions , such as sin() , cos() , tan() , asin() , acos() , atan() and atan2() , etc.

Now, with CSS’s trigonometry function, you can more easily arrange elements on a circle centered around a point:

Demo address: https://codepen.io/web-dot-dev/full/poGVqLO

If you are an animation enthusiast or often have the need to develop animations , then CSS triangle function will be your best assistant. During the animation development process, you can use CSS triangle function like this:

  • sin() function can be used to change element size or control animation duration;
  • cos() function can be used to keep the size of the rotated element unchanged;
  • tan() function can be used to draw parallelograms;
  • The asin() , acos() , atan() and atan2() functions can be used to rotate elements.

In addition, trigonometric functions have various applications and roles in animation. Here are some common examples:

  • Smooth motion and easing effects : By using trigonometric functions, especially sine ( sin() ) and cosine ( cos() ) functions, smooth motion and easing effects of elements can be achieved. This helps to make the animation look more natural and avoid sudden acceleration and deceleration.
  • Periodic Animation : The sine ( sin() ) and cosine ( cos() ) functions are periodic, so they are often used to create animation effects with looping or repeating actions. For example, by adjusting the parameters of the sine ( sin() ) function, ripple or oscillation effects can be created.
  • Rotation Animation : The rotational nature of trigonometric functions makes them ideal for creating object rotation animations. Smooth rotation effects can be achieved by using time variables in sine ( sin() ) and cosine ( cos() ) functions.
  • Path Animation : The periodicity and smoothness of trigonometric functions make them suitable for defining animations of objects moving along complex paths. Various path animations can be created by appropriately adjusting the parameters of trigonometric functions.
  • Oscillation effect : By using the sine ( sin() ) function, oscillation effects can be simulated, such as swinging or elastic animation of springs.
  • Phase and frequency adjustment : Adjusting the phase and frequency of the triangle function can change the speed and period of the animation, providing more creative control.

These are just some common applications of trigonometric functions in animation. Creative designers and developers can unleash more potential and create colorful and fascinating animation effects. For example, the following Ferris wheel rotating motion graphics applies CSS trigonometric functions.

Demo address: https://codepen.io/airen/full/JjxzWgW

You can learn more about CSS trigonometric functions in the Magic of Math: Exploring the Application of Math in Animation sessions.

💯 Subgrid

With CSS subgrid , you can create more complex grid layouts and achieve better alignment between sublayouts.

It allows a grid within another grid to take the rows and columns of the outer grid as its own by using subgrid as the values of the grid rows or columns.

Simply put, explicitly setting the value of display on a grid item to grid or inline-grid , or inheriting the display value of its parent grid container, means that the grid item is an independent grid formatting context. At the same time, when the grid-template-columns and/or grid-template-rows of the subgrid are explicitly set to subgrid , it means that the content of the subgrid participates in the formatting context of its parent grid, without establishing a new grid formatting context.

Subgrids in grid layouts are very useful and will give us more ways to achieve functionality that was previously impossible with CSS grids. Subgrids are great for aligning peers based on each other's dynamic content, and with subgrids , the layout can be adjusted to fit the content.

If you are interested in the subgrid layout features, you can read Subgrids and Nested Grids in Grid Layouts in Modern Web Layouts !

Typesetting

Web typesetting has always been very complex and involves a lot of knowledge. In the just past year of 2023, web typesetting has made some important updates. For example, you can use the text-wrap property to achieve layout adjustments , you can use initial-letter to achieve the effect of first letter sinking , and you can even use variable fonts and colored fonts on the web to provide users with a better reading experience.

👁️ the first word sinking

The first character sinking first appeared in print media such as newspapers, magazines, novels, textbooks, etc. It can add some fashion sense to the first letter of a chapter or paragraph. These sinking letters can attract readers’ attention and can also use very fancy fonts because they only process one letter in a string of text and do not affect the readability of the text.

The CSS internal connection layout module Level 3 (CSS Inline Layout Module Level 3) provides the initial-letter property that allows you to finely control the style of the first letter sinking. It can specify the size and number of sinking initials, concave initials, and raised initials.

p::first-letter {
initial-letter: 3 2;
}

Demo address: https://codepen.io/web-dot-dev/full/XWOKGaL

initial-letter is a small but beautiful CSS feature that can be used to style the placement of initials.

For a more detailed introduction to the CSS initial-letter feature, please read the course " Initial-letter Sinking: initial-letter " in " Modern CSS "!

👁️ balanced and beautiful

As a developer, you don’t know the final size, font size, or even language of the title or paragraph. All the variables needed to effectively and beautifully handle text wrapping are provided in the browser. Since the browser understands all factors (such as font size, language, and allocated area), it is very suitable for handling advanced and high-quality text layout.

This requires us to adopt two new text wrapping techniques, one called balance and the other called pretty . The balance value is designed to create a harmonious text block, while pretty is designed to prevent isolated characters and ensure healthy hyphenation. Traditionally, both tasks have been done manually, and it's great to hand this work over to the browser and have it support any translated language.

text-wrap: balance; There will be a limit on the number of lines, but this depends on how many lines are under the text width. When using text-wrap: balance; , because the browser has a limit on the number of lines for text wrapping, it should only be used for headings and subheadings. Applying it to large pieces of text will have no effect and will incur performance costs because the browser is still trying to calculate the best balance even though it will not apply anything.

When typesetting text, you need to choose between balance and aesthetics. For headings and subheadings, use text-wrap: balance; . For text paragraphs, use text-wrap: pretty; to eliminate isolated words in the last line. These features are good candidates for progressive enhancement. If someone is not in a supported browser, it will not have a negative impact on the experience, but it will improve the visual balance of the page in a supported browser.

For a more detailed introduction to the CSS text-wrap feature, please read the course " Classic Typesetting Techniques: Using text-wrap: balance to achieve text balance and line breaks " in " Modern CSS

Note that only two typesetting features, initial-letter and text-wrap , are introduced here. In fact, there are other typesetting features that will be supported by the Web platform in 2023. For example:

Color

2023 is the year of color for web platforms. With new color spaces and functions, dynamic color themes can be realized. You can create rich and bright themes, and customize them!

💯 high definition color space

URL:https://www.saji8k.com/displays/color-space/

The problem with color and the web is that CSS does not support high-definition preparations . When CSS was introduced to the web in 1996, most computer monitors were very bad and mostly not high-definition. Colors defined using RGB, HSL, or HEX (hexadecimal) were within the sRGB color gamut and only applicable to monitors at the time.

Nowadays, most new devices have wide color gamut display capabilities, such as using the Display P3 color gamut , and even larger color gamut like Rec.2020 . In 2023, we have new colors, more colors, new color spaces, color functions, and new features.

CSS and colors can now achieve:

  • Check if user screen hardware supports wide gamut HDR colors
  • Check if the user’s browser understands color syntax like OKLCH or Display P3
  • Specify HDR colors in color spaces such as OKLAB, OKLCH, HWB, Display P3, Rec.2020, XYZ, etc
  • Create gradual changes with HDR colors
  • Interpolate gradual changes in alternate color spaces
  • Use color-mix () to mix colors
  • Create color variants using relative color syntax

Demo address: https://codepen.io/web-dot-dev/full/yLZzmGM

CSS colors will be parsed in which color space, mainly divided into sRGB and non- sRGB . Among them, the colors parsed in the sRGB color space are:

  • Hexadecimal color
  • rgb () and rgba ()
  • hsl () and hsla ()
  • hwb ()
  • Name colors such as red , black etc

Colors parsed in non- sRGB color spaces are:

  • Lab and LCH: lab () and lch ()
  • OKLAB and OKLCH: oklab () and oklch ()
  • Any color space: color ()

For more detailed information on this, please refer to:

💯 color-mix () function

Blending colors is a classic task, and in 2023, CSS can also do it. You can not only mix white or black for colors, but also mix transparency, and perform all these operations in any color space you choose. Compared to traditional color mixing methods (such as simple average, linearly weighted average, etc.), the color-mix() function provides more flexible mixing methods. In addition, it can mix in different color spaces, which is more flexible when adjusting colors, and can choose the appropriate color space for mixing as needed.

You can think of color-mix() as a point in time in gradual change. In gradual change, we can see all the sections from blue to white, and color-mix() only shows one of the steps. Things get more complicated when you start thinking about color space and learning how much the mixed color space differs from the result.

URL: https://color-mix.style/

For a more detailed introduction to color-mix() , please read the course " Blending Colors in CSS: color-mix () " in " Modern CSS "!

👁️ relative color syntax

CSS Color Module Level 5 Introduces the relative color syntax for the CSS color function, further enhancing the color function functionality. This syntax allows you to define a new color based on another color. You can use it by first defining the starting color using the from keyword, and then specifying the channel for the new color in the color function as usual.

When you provide the starting color, you can access “channel keywords”, which allow you to reference each channel in the color space. The keyword depends on the color function you use. For rgb() , you will have r , g , and b channel keywords. For oklch() , you will have l , c , and h keywords. For each color function, you also have a transparent channel keyword that references the starting color's Alpha channel. For example:

:root {
--theme-primary: #8832CC;
}
.bg-primary-100 {
background-color: hsl(from var(--theme-primary) h s 90%);
}
.bg-primary-200 {
background-color: hsl(from var(--theme-primary) h s 80%);
}
.bg-primary-300 {
background-color: hsl(from var(--theme-primary) h s 70%);
}
.bg-primary-400 {
background-color: hsl(from var(--theme-primary) h s 60%);
}

Take hsl(from var(--theme-primary) h s 30%) as an example:

Demo address: https://codepen.io/airen/full/RweBMeY

Relative Color Syntax (RCS) is a supplement to color-mix() for creating color variants. It is more powerful than color-mix () , but also a different color processing strategy. color-mix() may mix in white to brighten the color, RCS can precisely access the brightness channel, and can use calc() on the channel to programmatically reduce or increase brightness.

Demo address: https://codepen.io/web-dot-dev/full/YzBrmdB

RCS allows you to manipulate colors relatively and absolutely. Relative variation refers to taking the current saturation or brightness value and modifying it using calc() . Absolute variation refers to replacing channel values with brand new values, such as setting opacity to 50% . This syntax can provide meaningful theme setting tools for time variants and so on.

For a more detailed introduction to Relative Color Syntax (RCS), please read the Relative Color Syntax in the course Color Formats in Modern CSS: RGB, HSL, HWB, LAB, and LCH in Modern CSS !

In addition, you can also use CSS’s accent-color and color-scheme to customize the UI color of Web controls , and use color-contrast() function to set the contrast of colors to improve User Experience!

👁️ Light-dark () function that responds to light or dark mode

To change the color based on whether light or dark mode is used, a prefers-color-scheme media query is often used. To make things easier, CSS now provides a useful function called light-dark() . This function accepts two color values as arguments. Depending on the color scheme you are currently using, it will output the first or second argument.

According to the specification :

If the color scheme used is light or unknown, the function calculates the value of the first color; if the color scheme used is dark, it calculates the value of the second color.

The color scheme used is based not only on the user’s light or dark mode settings, but also on the value of the color-scheme property. This is similar to how System Colors are calculated.

The color-scheme attribute allows an element to indicate which color scheme it is designed to use for rendering. These values are negotiated with the user's preferences to form a color scheme to use. This means that for light-dark() to work, you must also include a color-scheme declaration.

:root {
color-scheme: light dark;
}
:root {
--text-color: light-dark(#333, #ccc); /* 在浅色模式下返回第一个值。在深色模式下返回第二个值。 */
}

Since color-scheme is taken into account, this also means that you can override its value on each element to force it into a specific mode:

.dark {
color-scheme: dark; /* light-dark() 在此元素及其子元素上始终返回 dark */
}

Using the light-dark() function is much simpler and more convenient than using prefers-color-scheme media queries.

Responsive design

@Una Kravets Presented at the 2021 Google I/O Conference Proposed a new responsive design: Component-Driven Web Design . The web ecosystem is about to enter a new era of responsive web design, changing our perception of its meaning and bringing new changes to web design. Component-Driven Web Design (or development) is also known as the next generation of responsive web design .

In other words, we are once again witnessing the evolution of the responsive design ecosystem, namely CSS’s new features will be directly based on components rather than page-based style injection responsiveness This capability is called Component-Driven Web Design , and component-driven development will become a truly popular development model.

I also spent a class in “ Modern Web Layout “ to discuss this topic with you: “ Next Generation Responsive Web Design: Component-Driven Web Design “!

Two years later, in 2023, it can be said to be a breakthrough year for responsive web design. This year has led to a number of new features that have completely changed the way we build responsive web and pioneered a new pattern of component-based responsive design. The combination of CSS container queries ( size queries , style queries, and status queries ) and :has() selectors supports components to have their own responsive and logical styles based on the size of their parent elements and the presence or status of any child elements. This means that you can finally separate page-level layouts (macro layouts) from component-level layouts (micro layouts) and use your components everywhere with just one logic write!

Size Query 💯 Container Query

Container Query allows you to apply styles based on the size, computed style, and state of the element container. Its biggest features are: Container Query allows developers to define any element as containing context. The descendant elements of the query container can change style based on the size of the query container or changes in computed style and state !

In other words, a query container specifies its query type by using the container type attribute ( container-type or container ). At the same time, the style rules of the descendant elements of the query container can be set independently by using the @container conditional group rules. Simply put, Query containers (also known as CSS containment) provide a way to isolate various parts of the page and declare to the browser that these parts are independent of other parts of the page in terms of style and layout .

Container queries were originally limited to size queries, but over time, style queries and status queries were added to container queries. In other words, container queries include three types:

  • Size query : Adjust the style of its descendant elements according to the size of the query container
  • Style Query : Adjust the style of its descendant elements based on the query container style or CSS variables
  • State query : adjust the style of its descendant elements according to the query capacity state

The size query supports querying the size of the parent element, instead of using the global size information of the viewport (browser window) to apply CSS styles. This means that you can set dynamic styles for components in multiple layouts and views.

To use this feature, first set the element on the element you want to query, and then apply the style using @container with size parameters, similar to media queries. In addition to container queries, you can also get the container query size. In the following demonstration, the container query size cqi (representing the size of the embedded container) is used to adjust the size of the card header.

Demo address: https://codepen.io/web-dot-dev/full/eYxBNQy

If you are interested in this feature, you can move on to read “ Next Generation Responsive Web Design: Container Queries “ and “ CSS Container Queries: Size Queries “. Note that the cqi mentioned above is the container query unit, which is somewhat similar to the window unit. For more detailed information on this, please refer to " Relative Units in Modern CSS ".

👁️ Style Query for Container Query

Style queries are very similar to size queries. You can use style queries to query the computed style of a container, but distinguish size queries through the style () function, which accepts any valid style declaration. Style () function accepts:

@container style(font-style: italic) {
em {
background: var(--highlight);
color: var(--highlight-text);
}
}
@container style(--button: pill) {
button {
border-radius: 50%;
padding-inline: 1em;
}
}
@container colors style(background-color: black) {
a:any-link {
color: var(--link-on-dark);
}
}

Note that the conditions of the style query (as declared in the style () function) compare computed values.

Many times, style queries can also achieve the same results as size queries.

That is, you can query the value of a custom property on the parent element when using @container style() . For example, query whether a custom property value exists or is set to a specific value, such as @container style(--rain: true) :

Demo address: https://codepen.io/web-dot-dev/full/mdvBgqv

Although this sounds similar to using class names in CSS, style queries have some advantages. Firstly, for style queries, you can update the values in CSS according to the needs of pseudo-state. In addition, in future implementations, you will be able to query the range of values (such as style(60 < = --weather < = 70) ) and determine the applied style based on attribute value pairs (such as style(font-style: italic) ).

For a more detailed introduction to style queries, please read the course “ CSS Container Queries: Style Queries and Status Queries “ in “ Modern CSS “!

👁️ Status Query for Container Query

@Una Kravets shared a topic related to “ Current Status of CSS Community “ during CSS Day 2023, which includes topics related to the status query of CSS container queries.

In fact, CSS state queries and CSS style queries are somewhat similar. We mainly use the state() function to distinguish between size queries and style queries in CSS container queries. For example:

@container state(dir: rtl) {
/* RTL 布局 */
}

However, it is important to note that CSS state queries are only a new type of query currently being experimented with by the Chromium team.

💯 Update Media Query

With the update media query, you can adapt the interface to the refresh rate of the device. This feature can report fast , slow or none values, which are related to the functionality of different devices.

Most of the devices you design may have a fast refresh rate, including desktop devices and most mobile devices. The refresh rate of devices such as e-readers and low-energy payment systems may be slow. Knowing that the device cannot handle animations or frequent updates means you can save battery life or reduce erroneous view updates.

Demo address: https://codepen.io/web-dot-dev/full/wvNrVNa

When making animations, this media query is very useful if you want to reduce motion for users with slow networks. In addition, it is often used with the prefers-reduced-motion: reduce media query to provide different animation effects for users who have reduced motion preferences:

@media (prefers-reduced-motion: reduce), (update: slow)  {
*,
::before,
::after {
animation-delay: -1ms !important;
animation-duration: 1ms !important;
animation-iteration-count: 1 !important;
background-attachment: initial !important;
scroll-behavior: auto !important;
transition-duration: 0s !important;
transition-delay: 0s !important;
}
}

If you are interested in this area, especially how to make accessible web animations, you can move to read “ Web Animation Journey “ “ Key Tips for Improving Accessibility Animation “!

💯 Scripted media queries

Scripted media queries ( scripting ) can be used to check if JavaScript is available. This is very useful for progressive enhancement. Before this media query was introduced, a strategy for detecting whether JavaScript was available was to place a nojs class in HTML and then remove it using JavaScript. These scripts can be removed because CSS can now detect JavaScript and adjust accordingly.

.steam {
transition: opacity .2s ease;
}
@media (scripting: none) {
.steam {
opacity: 0;
}
}
@media (scripting: enabled) {
.steam {
opacity: 1;
}
}

Demo address: https://codepen.io/web-dot-dev/full/ExrwqrQ

Suppose there is a theme switch on a website. Since JavaScript is not available, script media queries can help make the switch comply with system preferences. Alternatively, consider using the switch component — if JavaScript is available, simply swipe the switch with gestures without having to turn it on and off. If the script is available, there are many opportunities to upgrade the User Experience; if the script is disabled, a meaningful basic experience can be provided.

👁️ Media queries with reduced transparency

Non-transparent interfaces can cause headaches or visual fatigue due to various types of visual defects. Therefore, Windows, macOS, and iOS have System Preferences that can reduce or remove the transparency of the interface. This media query for prefers-reduced-transparency is very suitable for media queries with other preferences, which allows you to be creative and adjust for users.

Demo address: https://codepen.io/web-dot-dev/full/RwvLXvO

In some cases, you can provide an alternate layout that does not overlay content on top of other content. In other cases, you can adjust the opacity of the color to opaque or almost opaque. @Adam Argyle’s blog post provides more inspiring demos that can be adjusted according to user preferences .

💯 Media query range

In media queries, min-width (or min-height ) and max-width (or max-height ) are called query ranges. Just using min- and max- is often confusing, at least for myself: "Using min-width and max-width is often confusing." Therefore, I always like to use the following figure to make judgments:

But the Media Queries Level 4 specification introduces a new syntax that uses common mathematical comparison operators such as < , > and = to determine the range of window widths, which makes more sense syntactically while writing less code and making it easier to understand the code.

/* 老方式的查询范围语法 */ 
@media (min-width: 375px) {
/* 视窗宽度大于或等于 375px */
}
@media (max-width: 768px) {
/* 视窗宽度小于或等于 768px */
}
@media (min-width: 375px) and (max-width: 768px) {
/* 视窗宽度在 375px ~ 768px 之间 */
}
/* 新式的查询范围语法 */
@media (width >= 375px) {
/* 视窗宽度大于或等于 375px */
}
@media (width <= 768px) {
/* 视窗宽度小于或等于 768px */
}
@media (375px <= width <= 768px) {
/* 视窗宽度在 375px ~ 768px 之间 */
}

The biggest change in the Media Queries Level 4 specification is that we have a new operator for comparing values instead of combining values.

  • < Calculate whether one value is less than another
  • > : Calculate whether one value is greater than another value
  • = : calculate whether one value is equal to another value
  • > = : calculate whether one value is greater than or equal to another value
  • < = Calculates whether one value is less than or equal to another

With these new operators, the syntax rules for CSS media queries have correspondingly changed to the following figure:

Usually, when we write CSS media queries, we create a so-called breakpoint, which is a design “interrupt” condition, and apply a set of styles to fix it. A design can have a bunch of breakpoints! They are usually based on a window between two widths: where the breakpoint starts and where it ends.

New Grammar Apart from the visual differences in grammar, they work slightly differently. Using min- and max- is equivalent to using mathematical comparison operators:

  • Max-width is equivalent to the < = operator, for example, (max-width: 320px) is the same as (width < = 320px)
  • Min-width is equivalent to the > = operator, for example, (min-width: 320px) is the same as (width > = 320px)

Note that neither is equivalent to the > or < operators.

For a more detailed introduction to CSS media queries, please read “ Modern CSS “ in “ CSS Media Query New Features: @media “!

Interactive animation

Interactive animation is the cornerstone of digital experience. It helps users obtain feedback on the content they click on and their position in virtual space. In 2023, many exciting features will be launched one after another, making interactive animation easier to organize and implement, achieving a smooth User Experience and a more refined network experience.

I am writing a small book related to web animation, if you are interested in web animation, you can pay attention to “ Web Animation Journey “!

👁️ view transition

View transitions can have a huge impact on the User Experience of the Web. With the CSS View Transitions API, you can create visual transitions between two page states in a Single Page Application. These transitions can be full-page transitions or smaller transitions on a webpage, such as adding or removing new items from a list.

The core of the CSS View Transitions API is the document.trigViewTranstion function. Pass in the function that updates the DOM to the new state, and this API takes care of all the work for you. To do this, it takes before and after snapshots and then transitions between the two. With CSS, you can control what is captured and customize how these snapshots are animated as needed.

:root {
view-transition-name: none;
}
::view-transition-group(*) {
animation-duration: 0.5s;
}

Demo address: https://codepen.io/web-dot-dev/full/ExrLGJx

For a more detailed introduction to view transitions, please read “ Using CSS View Transitions to Create Smooth Interface Motion Graphics “ in “ Web Animation Journey “; or see “ Modern CSS “ in “ Unlocking the Magic of CSS View Transitions API “!

👁️ Scroll drive motion graphics

Scroll-driven animations are an exciting feature offered since Chrome 115. They allow you to associate existing CSS animations or animations built using the Web Animations API with scroll offsets from the scrollers. When you scroll up and down, or left and right in the horizontal scrollers, the associated animations will rewind directly in response.

Using ScrollTimeline , you can track the overall progress of the scroller, as shown in the following demonstration. When you scroll to the end of the page, the text will be displayed character by character.

Demo address: https://codepen.io/web-dot-dev/full/JjxvwqG

Using ViewTimeline , you can track the movement of elements in the scrolling viewport. This is similar to how IntersectionObserver track elements. In the demonstration below, each image starts to gradually appear the moment it enters the scrolling viewport, until it is in the center position.

Demo address: https://codepen.io/web-dot-dev/full/XWOqovr

Due to the fact that scroll-driven animations work together with CSS animations and Web Animations APIs, you can benefit from all the advantages these APIs bring. This includes the ability to run these animations off the main thread. Now, with just a few extra lines of code, you can have silky smooth animations, driven by scroll operations, running off the main thread. What else wouldn’t you like?

When applying scroll-driven animation through CSS, the lookup mechanism that controls the scrollbar always traverses the DOM tree upwards, so it is limited to scrolling ancestor entities. However, usually, the element that needs to add animation effects is not a child element of the scrollbar, but an element located in a completely different subtree.

To allow an animation element to find a named scroll timeline for a non-ancestor entity, use the timeline-scope attribute on the shared parent. This allows you to attach a defined scroll-timeline or view-timeline with that name, giving it a broader scope. This way, any child of the shared parent can use a timeline with that name.

After timeline-scope is declared on the shared parent, the scroll-timeline declared on the scrollbar can be found using the scrollbar as an element of the animation-timeline .

Nowadays, we only need to use pure CSS to achieve it. By combining CSS scroll capture , custom properties , and scroll-driven motion graphics, we can achieve a parallax scrolling animation effect.

Demo address: https://codepen.io/airen/full/YzBMgQB

The above example also has a responsive function. When you reduce the browser screen to less than 768px , the page can also scroll the whole screen, and the parallax effect is more obvious:

For a more detailed introduction to CSS scroll-driven motion graphics, please read “The Art of CSS Scroll-Driven Motion Graphics “ in “ Web Animation Journey “; or see “ CSS Scroll-Driven Motion Graphics “ in “ Modern CSS “!

👁️ Discrete Property Animation

Another new feature in 2023 is the ability to animate discrete properties, such as between display: none and display: block . Starting from Chrome 116, you can use display and content-visibility in keyframe rules. You can also transition any discrete property at 50% instead of 0% . This is achieved by using the allowed-discrete value of the transition-behavior property, or as a shorthand in the transition property.

Transition-behavior property value allows-discrete , which allows for some smooth transitions to discrete properties. This makes it more flexible to apply transitions to discrete properties. This means that using the allow-discrete mode, you can achieve smooth transitions to discrete properties instead of sudden switches. This is very useful for situations where transitions need to be applied to discrete properties, making it possible to create smoother animation effects on these properties.

@layer transition {
.card {
transition: opacity 0.25s, display 0.25s;
transition-behavior: allow-discrete;
}
.fade-out {
opacity: 0;
display: none;
}
}

Demo address: https://codepen.io/airen/full/xxMxrgy

For a more detailed introduction to discrete property animation, you can read “ Web Animation Journey “ in “ Frame Animation and Transition Animation: Who is Better for Your Business Scenario “!

👁️ @starting-style

The above picture is from @XboxYan

@Starting-style is a new CSS @ rule that uses new web features to animate the entry and exit of elements with display: none . This rule provides a way for browsers to look for "before-open" styles before the element is opened on the page. This is useful for intro animations and for animating elements such as pop-ups or dialog boxes. It can also be used when creating an element and wanting to animate it. The following example animates the popover property to smoothly enter the view from outside the viewport and into the top layer.

/*   IS-OPEN STATE   */
dialog[open] {
translate: 0 0;
}
/* EXIT STATE */
dialog {
transition:
translate 0.7s ease-out,
overlay 0.7s ease-out,
display 0.7s ease-out allow-discrete;
translate: 0 100vh;
}
/* 0. BEFORE-OPEN STATE */
@starting-style {
dialog[open] {
translate: 0 100vh;
}
}

Demo address: https://codepen.io/web-dot-dev/full/OJdjjdX

For more information about @starting-style , see Frame Animation vs. Transition Animation: Who's Better for Your Business Scenario in Web Animation Journey !

👁️ overlay

New CSS overlay properties can be added to your transitions to allow elements with top-level styles (such as popover and dialog ) to smoothly move out of the top-level animation. If you do not use overlay transitions, your element will immediately return to the state of being cropped, transformed, and overwritten, and you will not see the transition occur. Similarly, when you add an overlay to a top-level element, :: backdrop can also be smoothly animated out.

Demo address: https://codepen.io/web-dot-dev/full/zYeJbgw

If you’re interested in entry and exit animations, or want to make a smooth entry and exit animation, see @Una Kravets and @Joey Arhar’s tutorial Four new CSS features for smooth entry and exit animations .

👁️ Anchor Positioning

CSS Anchor Positioning (CSS Anchor Positioning) is a new method for locating elements on a web page. It is a new feature of CSS. The W3C specification describes it as follows : “Through anchor positioning (through the anchor positioning function anchor() and anchor-size() ), an absolutely positioned element can be anchored with one or more other elements on the page, while also allowing them to try multiple possible positions to find the best position to avoid overlap and overflow".

Simply put, CSS anchor positioning improves the ability of element absolute positioning. Web developers can use a simpler and more natural way to locate the relationship between elements, allowing page elements to be positioned and adjusted according to the position and size of other elements within their containing blocks. The emergence of this feature provides web developers with more control and flexibility, while reducing dependence on JavaScript, making page performance more optimized.

CSS anchor positioning provides a new paradigm for positioning in web layout by introducing a set of properties and values that allow elements to connect with each other.

  • First, use anchor-name to define an anchor point, and the marked element will serve as the benchmark target for absolute positioning
  • Second, use the anchor() or anchor-size() function as the value of the embedded property ( top , right , bottom , left or their logical equivalents) of the element being positioned
  • Finally, using the @position-fallback rule provides a fallback mechanism for anchor positioning, that is, setting multiple sets of different anchor positioning rules to adapt to more complex web layouts

In the past, to achieve the effect of the lava lamp menu, we had to rely on JavaScript scripts. Now, we can use CSS anchor positioning to achieve it. For example:

Demo address: https://codepen.io/airen/full/RwEpMxM

If you want to learn more about CSS anchor positioning, read CSS Anchor Positioning: Exploring the Next Generation of Web Layouts in Modern CSS !

👁️ animation compositing

The W3C specification describes CSS compositing animations as follows :

The animation-composition property defines the composite operation used when multiple animations affect the same property simultaneously.

Roughly speaking, “The animation-composition property defines the composite operation used when multiple animations affect the same property at the same time."

In other words, CSS animation compositing ( animation-composition ) refers to using multiple CSS animation effects to affect the same property at the same time, and controlling how these animations combine to affect the property values of the animation element through some properties and methods. This allows for more flexible control of the animation performance when multiple animation effects act on the element at the same time, including the overlay and replacement of property values. This provides web developers with more control to create complex animation effects without relying on a single animation rule.

For a more detailed introduction to animation-composition , you can refer to " Multiple CSS Animations and Animation Compositing: Creating More Complex Animation Effects " in " Web Animation Journey ", or you can read " Modern CSS " in " CSS Animation Compositing: animation-composition "!

👁️ Slowdown function linear ()

Don’t let the name of this function mislead you. linear() function (not to be confused with the linear keyword) allows you to create complex easing functions in a simple way, at the expense of some precision.

Before the introduction of linear() (published in Chrome 113), it was not possible to create bounce or spring effects in CSS. Thanks to linear() , these easing functions can be approximated by simplifying them into a series of points and then linearly interpolating between these points.

:root {
--linear: linear(0, 1);
--quad-in: linear( 0, 0.0039, 0.0156, 0.0352, 0.0625, 0.0977, 0.1407, 0.1914, 0.2499, 0.3164, 0.3906 62.5%, 0.5625, 0.7656, 1 );
--quad-out: linear( 0, 0.2342, 0.4374, 0.6093 37.49%, 0.6835, 0.7499, 0.8086, 0.8593, 0.9023, 0.9375, 0.9648, 0.9844, 0.9961, 1 );
--quad-in-out: linear( 0, 0.0027, 0.0106 7.29%, 0.0425, 0.0957, 0.1701 29.16%, 0.2477, 0.3401 41.23%, 0.5982 55.18%, 0.7044 61.56%, 0.7987, 0.875 75%, 0.9297, 0.9687, 0.9922, 1 );
--power-1-in: linear( 0, 0.0039, 0.0156, 0.0352, 0.0625, 0.0977, 0.1407, 0.1914, 0.2499, 0.3164, 0.3906 62.5%, 0.5625, 0.7656, 1 );
--power-1-out: linear( 0, 0.2342, 0.4374, 0.6093 37.49%, 0.6835, 0.7499, 0.8086, 0.8593, 0.9023, 0.9375, 0.9648, 0.9844, 0.9961, 1 );
--power-1-in-out: linear( 0, 0.0027, 0.0106 7.29%, 0.0425, 0.0957, 0.1701 29.16%, 0.2477, 0.3401 41.23%, 0.5982 55.18%, 0.7044 61.56%, 0.7987, 0.875 75%, 0.9297, 0.9687, 0.9922, 1 );
--cubic-in: linear( 0, 0.0014 11.11%, 0.0071 19.24%, 0.0188 26.6%, 0.037 33.33%, 0.0634 39.87%, 0.0978 46.07%, 0.1407 52.02%, 0.1925 57.74%, 0.2559 63.49%, 0.3295 69.07%, 0.4135 74.5%, 0.5083 79.81%, 0.6141 85%, 0.7312 90.09%, 1 );
--cubic-out: linear( 0, 0.2688 9.91%, 0.3859 15%, 0.4917 20.19%, 0.5865 25.5%, 0.6705 30.93%, 0.7441 36.51%, 0.8075 42.26%, 0.8593 47.98%, 0.9022 53.93%, 0.9366 60.13%, 0.963 66.67%, 0.9812 73.4%, 0.9929 80.76%, 0.9986 88.89%, 1 );
--cubic-in-out: linear( 0, 0.0036 9.62%, 0.0185 16.66%, 0.0489 23.03%, 0.0962 28.86%, 0.1705 34.93%, 0.269 40.66%, 0.3867 45.89%, 0.5833 52.95%, 0.683 57.05%, 0.7829 62.14%, 0.8621 67.46%, 0.8991 70.68%, 0.9299 74.03%, 0.9545 77.52%, 0.9735 81.21%, 0.9865 85%, 0.9949 89.15%, 1 );
--power-2-in: linear( 0, 0.0014 11.11%, 0.0071 19.24%, 0.0188 26.6%, 0.037 33.33%, 0.0634 39.87%, 0.0978 46.07%, 0.1407 52.02%, 0.1925 57.74%, 0.2559 63.49%, 0.3295 69.07%, 0.4135 74.5%, 0.5083 79.81%, 0.6141 85%, 0.7312 90.09%, 1 );
--power-2-out: linear( 0, 0.2688 9.91%, 0.3859 15%, 0.4917 20.19%, 0.5865 25.5%, 0.6705 30.93%, 0.7441 36.51%, 0.8075 42.26%, 0.8593 47.98%, 0.9022 53.93%, 0.9366 60.13%, 0.963 66.67%, 0.9812 73.4%, 0.9929 80.76%, 0.9986 88.89%, 1 );
--power-2-in-out: linear( 0, 0.0036 9.62%, 0.0185 16.66%, 0.0489 23.03%, 0.0962 28.86%, 0.1705 34.93%, 0.269 40.66%, 0.3867 45.89%, 0.5833 52.95%, 0.683 57.05%, 0.7829 62.14%, 0.8621 67.46%, 0.8991 70.68%, 0.9299 74.03%, 0.9545 77.52%, 0.9735 81.21%, 0.9865 85%, 0.9949 89.15%, 1 );
--quart-in: linear( 0, 0.0039 25%, 0.0117 32.89%, 0.0248 39.68%, 0.0457 46.22%, 0.0743 52.21%, 0.1113 57.77%, 0.1575 63%, 0.218 68.33%, 0.2901 73.39%, 0.3745 78.23%, 0.4718 82.88%, 0.5827 87.37%, 0.7074 91.71%, 0.8462 95.91%, 1 );
--quart-out: linear( 0, 0.1538 4.09%, 0.2926 8.29%, 0.4173 12.63%, 0.5282 17.12%, 0.6255 21.77%, 0.7099 26.61%, 0.782 31.67%, 0.8425 37%, 0.8887 42.23%, 0.9257 47.79%, 0.9543 53.78%, 0.9752 60.32%, 0.9883 67.11%, 0.9961 75%, 1 );
--quart-in-out: linear( 0, 0.0029 13.8%, 0.0184 21.9%, 0.0339 25.51%, 0.0551 28.81%, 0.0827 31.88%, 0.1168 34.76%, 0.1962 39.57%, 0.3005 44.02%, 0.4084 47.53%, 0.6242 53.45%, 0.7493 57.93%, 0.8495 62.97%, 0.8888 65.67%, 0.9213 68.51%, 0.9629 73.9%, 0.9876 80.16%, 0.998 87.5%, 1 );
--power-3-in: linear( 0, 0.0039 25%, 0.0117 32.89%, 0.0248 39.68%, 0.0457 46.22%, 0.0743 52.21%, 0.1113 57.77%, 0.1575 63%, 0.218 68.33%, 0.2901 73.39%, 0.3745 78.23%, 0.4718 82.88%, 0.5827 87.37%, 0.7074 91.71%, 0.8462 95.91%, 1 );
--power-3-out: linear( 0, 0.1538 4.09%, 0.2926 8.29%, 0.4173 12.63%, 0.5282 17.12%, 0.6255 21.77%, 0.7099 26.61%, 0.782 31.67%, 0.8425 37%, 0.8887 42.23%, 0.9257 47.79%, 0.9543 53.78%, 0.9752 60.32%, 0.9883 67.11%, 0.9961 75%, 1 );
--power-3-in-out: linear( 0, 0.0029 13.8%, 0.0184 21.9%, 0.0339 25.51%, 0.0551 28.81%, 0.0827 31.88%, 0.1168 34.76%, 0.1962 39.57%, 0.3005 44.02%, 0.4084 47.53%, 0.6242 53.45%, 0.7493 57.93%, 0.8495 62.97%, 0.8888 65.67%, 0.9213 68.51%, 0.9629 73.9%, 0.9876 80.16%, 0.998 87.5%, 1 );
--quint-in: linear( 0, 0.0024 29.91%, 0.008 38.03%, 0.0179 44.72%, 0.035 51.16%, 0.0595 56.88%, 0.0922 62.08%, 0.1338 66.88%, 0.1914 71.85%, 0.262 76.5%, 0.3461 80.88%, 0.4447 85.04%, 0.5587 89.01%, 0.689 92.82%, 0.8359 96.48%, 1 );
--quint-out: linear( 0, 0.1641 3.52%, 0.311 7.18%, 0.4413 10.99%, 0.5553 14.96%, 0.6539 19.12%, 0.738 23.5%, 0.8086 28.15%, 0.8662 33.12%, 0.9078 37.92%, 0.9405 43.12%, 0.965 48.84%, 0.9821 55.28%, 0.992 61.97%, 0.9976 70.09%, 1 );
--quint-in-out: linear( 0, 0.0012 14.95%, 0.0089 22.36%, 0.0297 28.43%, 0.0668 33.43%, 0.0979 36.08%, 0.1363 38.55%, 0.2373 43.07%, 0.3675 47.01%, 0.5984 52.15%, 0.7121 55.23%, 0.8192 59.21%, 0.898 63.62%, 0.9297 66.23%, 0.9546 69.06%, 0.9733 72.17%, 0.9864 75.67%, 0.9982 83.73%, 1 );
--power-4-in: linear( 0, 0.0024 29.91%, 0.008 38.03%, 0.0179 44.72%, 0.035 51.16%, 0.0595 56.88%, 0.0922 62.08%, 0.1338 66.88%, 0.1914 71.85%, 0.262 76.5%, 0.3461 80.88%, 0.4447 85.04%, 0.5587 89.01%, 0.689 92.82%, 0.8359 96.48%, 1 );
--power-4-out: linear( 0, 0.1641 3.52%, 0.311 7.18%, 0.4413 10.99%, 0.5553 14.96%, 0.6539 19.12%, 0.738 23.5%, 0.8086 28.15%, 0.8662 33.12%, 0.9078 37.92%, 0.9405 43.12%, 0.965 48.84%, 0.9821 55.28%, 0.992 61.97%, 0.9976 70.09%, 1 );
--power-4-in-out: linear( 0, 0.0012 14.95%, 0.0089 22.36%, 0.0297 28.43%, 0.0668 33.43%, 0.0979 36.08%, 0.1363 38.55%, 0.2373 43.07%, 0.3675 47.01%, 0.5984 52.15%, 0.7121 55.23%, 0.8192 59.21%, 0.898 63.62%, 0.9297 66.23%, 0.9546 69.06%, 0.9733 72.17%, 0.9864 75.67%, 0.9982 83.73%, 1 );
--strong-in: linear( 0, 0.0024 29.91%, 0.008 38.03%, 0.0179 44.72%, 0.035 51.16%, 0.0595 56.88%, 0.0922 62.08%, 0.1338 66.88%, 0.1914 71.85%, 0.262 76.5%, 0.3461 80.88%, 0.4447 85.04%, 0.5587 89.01%, 0.689 92.82%, 0.8359 96.48%, 1 );
--strong-out: linear( 0, 0.1641 3.52%, 0.311 7.18%, 0.4413 10.99%, 0.5553 14.96%, 0.6539 19.12%, 0.738 23.5%, 0.8086 28.15%, 0.8662 33.12%, 0.9078 37.92%, 0.9405 43.12%, 0.965 48.84%, 0.9821 55.28%, 0.992 61.97%, 0.9976 70.09%, 1 );
--strong-in-out: linear( 0, 0.0012 14.95%, 0.0089 22.36%, 0.0297 28.43%, 0.0668 33.43%, 0.0979 36.08%, 0.1363 38.55%, 0.2373 43.07%, 0.3675 47.01%, 0.5984 52.15%, 0.7121 55.23%, 0.8192 59.21%, 0.898 63.62%, 0.9297 66.23%, 0.9546 69.06%, 0.9733 72.17%, 0.9864 75.67%, 0.9982 83.73%, 1 );
--elastic-in: linear( 0, 0.0019 13.34%, -0.0056 27.76%, -0.0012 31.86%, 0.0147 39.29%, 0.0161 42.46%, 0.0039 46.74%, -0.0416 54.3%, -0.046 57.29%, -0.0357, -0.0122 61.67%, 0.1176 69.29%, 0.1302 70.79%, 0.1306 72.16%, 0.1088 74.09%, 0.059 75.99%, -0.0317 78.19%, -0.3151 83.8%, -0.3643 85.52%, -0.3726, -0.3705 87.06%, -0.3463, -0.2959 89.3%, -0.1144 91.51%, 0.7822 97.9%, 1 );
--elastic-out: linear( 0, 0.2178 2.1%, 1.1144 8.49%, 1.2959 10.7%, 1.3463 11.81%, 1.3705 12.94%, 1.3726, 1.3643 14.48%, 1.3151 16.2%, 1.0317 21.81%, 0.941 24.01%, 0.8912 25.91%, 0.8694 27.84%, 0.8698 29.21%, 0.8824 30.71%, 1.0122 38.33%, 1.0357, 1.046 42.71%, 1.0416 45.7%, 0.9961 53.26%, 0.9839 57.54%, 0.9853 60.71%, 1.0012 68.14%, 1.0056 72.24%, 0.9981 86.66%, 1 );
--elastic-in-out: linear( 0, 0.0009 8.51%, -0.0047 19.22%, 0.0016 22.39%, 0.023 27.81%, 0.0237 30.08%, 0.0144 31.81%, -0.0051 33.48%, -0.1116 39.25%, -0.1181 40.59%, -0.1058 41.79%, -0.0455, 0.0701 45.34%, 0.9702 55.19%, 1.0696 56.97%, 1.0987 57.88%, 1.1146 58.82%, 1.1181 59.83%, 1.1092 60.95%, 1.0057 66.48%, 0.986 68.14%, 0.9765 69.84%, 0.9769 72.16%, 0.9984 77.61%, 1.0047 80.79%, 0.9991 91.48%, 1 );
--bounce-in: linear( 0, 0.0117, 0.0156, 0.0117, 0, 0.0273, 0.0468, 0.0586, 0.0625, 0.0586, 0.0468, 0.0273, 0 27.27%, 0.1093, 0.1875 36.36%, 0.2148, 0.2343, 0.2461, 0.25, 0.2461, 0.2344, 0.2148 52.28%, 0.1875 54.55%, 0.1095, 0, 0.2341, 0.4375, 0.6092, 0.75, 0.8593, 0.9375 90.91%, 0.9648, 0.9843, 0.9961, 1 );
--bounce-out: linear( 0, 0.0039, 0.0157, 0.0352, 0.0625 9.09%, 0.1407, 0.25, 0.3908, 0.5625, 0.7654, 1, 0.8907, 0.8125 45.45%, 0.7852, 0.7657, 0.7539, 0.75, 0.7539, 0.7657, 0.7852, 0.8125 63.64%, 0.8905, 1 72.73%, 0.9727, 0.9532, 0.9414, 0.9375, 0.9414, 0.9531, 0.9726, 1, 0.9883, 0.9844, 0.9883, 1 );
--bounce-in-out: linear( 0, 0.0078, 0, 0.0235, 0.0313, 0.0235, 0.0001 13.63%, 0.0549 15.92%, 0.0938, 0.1172, 0.125, 0.1172, 0.0939 27.26%, 0.0554 29.51%, 0.0003 31.82%, 0.2192, 0.3751 40.91%, 0.4332, 0.4734 45.8%, 0.4947 48.12%, 0.5027 51.35%, 0.5153 53.19%, 0.5437, 0.5868 57.58%, 0.6579, 0.7504 62.87%, 0.9999 68.19%, 0.9453, 0.9061, 0.8828, 0.875, 0.8828, 0.9063, 0.9451 84.08%, 0.9999 86.37%, 0.9765, 0.9688, 0.9765, 1, 0.9922, 1 );
--expo-in: linear( 0, 0.0085 31.26%, 0.0167 40.94%, 0.0289 48.86%, 0.0471 55.92%, 0.0717 61.99%, 0.1038 67.32%, 0.1443 72.07%, 0.1989 76.7%, 0.2659 80.89%, 0.3465 84.71%, 0.4419 88.22%, 0.554 91.48%, 0.6835 94.51%, 0.8316 97.34%, 1 );
--expo-out: linear( 0, 0.1684 2.66%, 0.3165 5.49%, 0.446 8.52%, 0.5581 11.78%, 0.6535 15.29%, 0.7341 19.11%, 0.8011 23.3%, 0.8557 27.93%, 0.8962 32.68%, 0.9283 38.01%, 0.9529 44.08%, 0.9711 51.14%, 0.9833 59.06%, 0.9915 68.74%, 1 );
--expo-in-out: linear( 0, 0.0053 17.18%, 0.0195 26.59%, 0.0326 30.31%, 0.0506 33.48%, 0.0744 36.25%, 0.1046 38.71%, 0.1798 42.62%, 0.2846 45.93%, 0.3991 48.37%, 0.6358 52.29%, 0.765 55.45%, 0.8622 59.3%, 0.8986 61.51%, 0.9279 63.97%, 0.9481 66.34%, 0.9641 69.01%, 0.9856 75.57%, 0.9957 84.37%, 1 );
--circ-in: linear( -0, 0.0048 9.8%, 0.0192 19.5%, 0.043 29.02%, 0.0761 38.26%, 0.1181 47.13%, 0.1685 55.56%, 0.227 63.44%, 0.2929 70.71%, 0.3656 77.3%, 0.4445 83.15%, 0.5285 88.19%, 0.6173 92.39%, 0.7099 95.7%, 0.805 98.08%, 0.9021 99.52%, 1 );
--circ-out: linear( 0, 0.0979 0.48%, 0.195 1.92%, 0.2901 4.3%, 0.3827 7.61%, 0.4715 11.81%, 0.5555 16.85%, 0.6344 22.7%, 0.7071 29.29%, 0.773 36.56%, 0.8315 44.44%, 0.8819 52.87%, 0.9239 61.74%, 0.957 70.98%, 0.9808 80.5%, 0.9952 90.2%, 1 );
--circ-in-out: linear( -0, 0.0033 5.75%, 0.0132 11.43%, 0.0296 16.95%, 0.0522 22.25%, 0.0808 27.25%, 0.1149 31.89%, 0.1542 36.11%, 0.1981 39.85%, 0.2779 44.79%, 0.3654 48.15%, 0.4422 49.66%, 0.5807 50.66%, 0.6769 53.24%, 0.7253 55.37%, 0.7714 58.01%, 0.8142 61.11%, 0.8536 64.65%, 0.9158 72.23%, 0.9619 80.87%, 0.9904 90.25%, 1 );
--sine-in: linear( 0, 0.0035, 0.0141 10.7%, 0.0318 16.09%, 0.0566 21.51%, 0.0885 26.98%, 0.1278 32.53%, 0.2288 43.93%, 0.3563 55.48%, 0.5171 67.92%, 0.7139 81.53%, 1 );
--sine-out: linear( 0, 0.2861 18.47%, 0.4829 32.08%, 0.6437 44.52%, 0.7712 56.07%, 0.8722 67.47%, 0.9115 73.02%, 0.9434 78.49%, 0.9682 83.91%, 0.9859 89.3%, 0.9965, 1 );
--sine-in-out: linear( 0, 0.007 5.35%, 0.0282 10.75%, 0.0638 16.26%, 0.1144 21.96%, 0.1833 28.16%, 0.2717 34.9%, 0.6868 62.19%, 0.775 68.54%, 0.8457 74.3%, 0.9141 81.07%, 0.9621 87.52%, 0.9905 93.8%, 1 );
--back-in: linear( 0, -0.0029 4.31%, -0.0119 9.02%, -0.0838 31.27%, -0.0956 36.64%, -0.1 41.45%, -0.0953 47.03%, -0.0792 52.25%, -0.0512 57.19%, -0.0111 61.92%, 0.0512 67.19%, 0.131 72.27%, 0.2284 77.18%, 0.3443 81.96%, 0.479 86.62%, 0.6329 91.17%, 0.8065 95.63%, 1 );
--back-out: linear( 0, 0.1935 4.37%, 0.3671 8.83%, 0.521 13.38%, 0.6557 18.04%, 0.7716 22.82%, 0.869 27.73%, 0.9488 32.81%, 1.0111 38.08%, 1.0512 42.81%, 1.0792 47.75%, 1.0953 52.97%, 1.1 58.55%, 1.0956 63.36%, 1.0838 68.73%, 1.0119 90.98%, 1.0029 95.69%, 1 );
--back-in-out: linear( 0, -0.0077 5.2%, -0.0452 16.98%, -0.0493 22.35%, -0.0418 25.57%, -0.0258 28.57%, -0.0007 31.42%, 0.0335 34.15%, 0.1242 39.03%, 0.2505 43.65%, 0.3844 47.35%, 0.656 53.68%, 0.81 58.37%, 0.9282 63.52%, 0.9719 66.23%, 1.0055 69.04%, 1.0255 71.4%, 1.0396 73.87%, 1.0477 76.48%, 1.05 79.27%, 1.0419 84.36%, 1.0059 95.49%, 1 );
--spring-1: linear(0, 0.006, 0.025 2.8%, 0.101 6.1%, 0.539 18.9%, 0.721 25.3%, 0.849 31.5%,0.937 38.1%, 0.968 41.8%, 0.991 45.7%, 1.006 50.1%, 1.015 55%, 1.017 63.9%,1.001);
--spring-2: linear(0, 0.007, 0.029 2.2%, 0.118 4.7%, 0.625 14.4%, 0.826 19%, 0.902, 0.962,1.008 26.1%, 1.041 28.7%, 1.064 32.1%, 1.07 36%, 1.061 40.5%, 1.015 53.4%,0.999 61.6%, 0.995 71.2%, 1);
--spring-3: linear(0, 0.009, 0.035 2.1%, 0.141 4.4%, 0.723 12.9%, 0.938 16.7%, 1.017, 1.077,1.121, 1.149 24.3%, 1.159, 1.163, 1.161, 1.154 29.9%, 1.129 32.8%,1.051 39.6%, 1.017 43.1%, 0.991, 0.977 51%, 0.974 53.8%, 0.975 57.1%,0.997 69.8%, 1.003 76.9%, 1);
--spring-4: linear(0, 0.009, 0.037 1.7%, 0.153 3.6%, 0.776 10.3%, 1.001, 1.142 16%, 1.185, 1.209 19%, 1.215 19.9% 20.8%, 1.199, 1.165 25%, 1.056 30.3%, 1.008 33%, 0.973,0.955 39.2%, 0.953 41.1%, 0.957 43.3%, 0.998 53.3%, 1.009 59.1% 63.7%,0.998 78.9%, 1);
--spring-5: linear(0, 0.01, 0.04 1.6%, 0.161 3.3%, 0.816 9.4%, 1.046, 1.189 14.4%, 1.231,1.254 17%, 1.259, 1.257 18.6%, 1.236, 1.194 22.3%, 1.057 27%, 0.999 29.4%,0.955 32.1%, 0.942, 0.935 34.9%, 0.933, 0.939 38.4%, 1 47.3%, 1.011,1.017 52.6%, 1.016 56.4%, 1 65.2%, 0.996 70.2%, 1.001 87.2%, 1);
--bounce-1: linear(0, 0.004, 0.016, 0.035, 0.063, 0.098, 0.141, 0.191, 0.25, 0.316, 0.391 36.8%,0.563, 0.766, 1 58.8%, 0.946, 0.908 69.1%, 0.895, 0.885, 0.879, 0.878, 0.879,0.885, 0.895, 0.908 89.7%, 0.946, 1);
--bounce-2: linear(0, 0.004, 0.016, 0.035, 0.063, 0.098, 0.141 15.1%, 0.25, 0.391, 0.562, 0.765,1, 0.892 45.2%, 0.849, 0.815, 0.788, 0.769, 0.757, 0.753, 0.757, 0.769, 0.788,0.815, 0.85, 0.892 75.2%, 1 80.2%, 0.973, 0.954, 0.943, 0.939, 0.943, 0.954,0.973, 1);
--bounce-3: linear(0, 0.004, 0.016, 0.035, 0.062, 0.098, 0.141 11.4%, 0.25, 0.39, 0.562, 0.764,1 30.3%, 0.847 34.8%, 0.787, 0.737, 0.699, 0.672, 0.655, 0.65, 0.656, 0.672,0.699, 0.738, 0.787, 0.847 61.7%, 1 66.2%, 0.946, 0.908, 0.885 74.2%, 0.879,0.878, 0.879, 0.885 79.5%, 0.908, 0.946, 1 87.4%, 0.981, 0.968, 0.96, 0.957, 0.96, 0.968, 0.981, 1);
--bounce-4: linear(0, 0.004, 0.016 3%, 0.062, 0.141, 0.25, 0.391, 0.562 18.2%, 1 24.3%, 0.81,0.676 32.3%, 0.629, 0.595, 0.575, 0.568, 0.575, 0.595, 0.629, 0.676 48.2%,0.811, 1 56.2%, 0.918, 0.86, 0.825, 0.814, 0.825, 0.86, 0.918, 1 77.2%,0.94 80.6%, 0.925, 0.92, 0.925, 0.94 87.5%, 1 90.9%, 0.974, 0.965, 0.974, 1);
--bounce-5: linear(0, 0.004, 0.016 2.5%, 0.063, 0.141, 0.25 10.1%, 0.562, 1 20.2%, 0.783, 0.627,0.534 30.9%, 0.511, 0.503, 0.511, 0.534 38%, 0.627, 0.782, 1 48.7%, 0.892,0.815, 0.769 56.3%, 0.757, 0.753, 0.757, 0.769 61.3%, 0.815, 0.892, 1 68.8%,0.908 72.4%, 0.885, 0.878, 0.885, 0.908 79.4%, 1 83%, 0.954 85.5%, 0.943,0.939, 0.943, 0.954 90.5%, 1 93%, 0.977, 0.97, 0.977, 1);
}

These easing curves will make your animation more dynamic, weighty, etc. They bring the animation closer to the movement of objects in real life.

Demo address: https://codepen.io/web-dot-dev/full/bGzMOJM

For a more detailed introduction to the linear() function, see Using Linear () Function to Create Stunning Animated Curves in Web Animation Journey !

👁️ Scrollend incident

Many interfaces include scrolling interactions, and sometimes interfaces need to synchronize information related to the current scrolling position or extract data based on the current state. Before the scrollend event, you have to use an inaccurate timeout method that can be triggered when the user's finger is still on the screen. With the scrollend event, you can implement precisely timed scrollend events to see if the user is still performing gesture operations.

Demo address: https://codepen.io/web-dot-dev/full/OJdxKqJ

This is very important for browsers because during scrolling, JavaScript cannot track the presence of fingers on the screen, and relevant information cannot be obtained. Now, a large amount of inaccurate scrolling end attempt code can be removed and replaced with high-precision events owned by the browser.

For a more detailed introduction to the scrollend event, see @Adam Argyle's Scrollend (a new JavaScript event) !

💯 Scroll Capture

Actually, scroll capture is not a feature that will just be supported in 2023, but I still included this feature in this article. One of the main reasons is that it can really help us improve the user experience. It is a very good and easy-to-use feature.

CSS Scroll Capture gives us a way to, scroll a document to a specific point (location) as the user scrolls through it . This is helpful for creating a more application-like (native Client) experience for certain types of applications (such as <Carousel> pieces) on mobile devices, and even on desktops. In short, CSS Scroll Capture can:

  • Prevent awkward scrolling positions when scrolling.
  • Create a better scrolling experience.

CSS scroll capture related properties are similar to CSS Flexbox and Grid properties, divided into properties that act on containers (scroll containers) and properties that act on positioning sub-items (scroll container sub-elements) . The properties that act on scroll containers mainly include scroll-snap-type , scroll-padding and scroll-snap-stop ; the properties that act on positioning sub-items mainly include scroll-margin and scroll-snap-align .

Now, you can combine scroll capture with scroll-driven animation and custom scroll bars to achieve a 3D cover effect like the one shown below without relying on any JavaScript.

Demo address: https://codepen.io/airen/full/yLZWJog

What you need to know is that besides scroll capture , there are other ways to improve the user’s scrolling experience. For more details, please refer to “ How CSS Improves Scrolling Experience “ in “ Defensive CSS Insights “, “ Beautiful Scrolbar UI: Custom Scrolbar UI “ and “ CSS Scrolling Capture “!

Review of past issues

First of all, I want to declare that the content introduced earlier is the fastest developing part of CSS features in my opinion in 2023! In addition, some of the above content is excerpted from Chrome team’s just released “ CSS Wrapped: 2023! “, but I abandoned the introduction of components, mainly because this part is more related to HTML.

Actually, since 2020, I have had a habit of publishing a summary article about new CSS features every year. If you are interested in past content, you can read the following articles:

If you are also interested in CSS, you can also follow my brochure.

  • Modern Web Layout “: focuses on modern CSS features that can be used for web layout
  • Modern CSS “: mainly talks about the latest features in the CSS field, the features introduced earlier, basically can be found in this booklet
  • Web Animation Journey “: mainly tells how to make Web animation, from theory, design principles to practice, if you like animation, then the content of this booklet you will love
  • Defensive CSS Intensive Course “: Mainly tells us that when we write CSS, we should write it with the mentality of “what if”. This booklet can also be called a collection of CSS skills, which can really help you solve many CSS problems encountered in production

Written at the end

CSS has been a great success in the past few years (especially in 2023). If you are interested in CSS, or want to improve your skills in this area and get the latest features of CSS in a timely manner, please follow me! I will take you to experience different CSS!

--

--

w3cplus
w3cplus

Written by w3cplus

Author of "Modern CSS," "Modern Web Layout," "In-Depth CSS Defense," and "A Journey into Web Animation!"