跪拜 Guibai
← Back to the summary

26 Weeks of Front-End: New CSS, JS, and HTML APIs That Shipped in H1 2026

Week 1 Dec 29 – Jan 4

This week I learned about constructing CSS styles using CSSStyleSheet.

When inserting a brand-new block of CSS styles into a page, most front-end developers do it by creating a <style> element and inserting a string of CSS code.

The drawback of this approach is obvious: it's difficult to perform fine-grained operations. For example, to modify, delete, or query a specific CSS rule, you must manually parse the entire massive CSS string, which is both tedious and error-prone.

Thus, the CSSStyleSheet() constructor was born, specifically designed for creating CSS styles.

// Construct a blank stylesheet
const sheet = new CSSStyleSheet();
// Add corresponding CSS rules to the stylesheet
sheet.replaceSync("article h3 { text-shadow: 2px 2px 4px #0006; }");
// Add it to the page
document.adoptedStyleSheets.push(sheet);

It also provides several methods specifically for inserting, deleting, and otherwise processing styles.

Compatibility is good.

If interested, visit here: Learn to Use CSSStyleSheet to Construct CSS Styles

Week 2 Jan 5 – Jan 11

Learned to use pure CSS to achieve the effect of connecting elements with straight lines or arrows.

Mainly uses CSS anchor positioning and some CSS image drawing techniques.

Implementing this effect turned out to be more complex than I initially expected.

Demo page address see here.

Article address: Pure CSS Implementation of Polyline Connecting Two Arbitrary Elements

Week 3 Jan 12 – Jan 18

This week I learned about the CSS text-decoration-inset property.

It can change the left and right indentation size of underlines.

Compatibility is currently poor; only Firefox supports it.

If interested, visit here to learn more: First Introduction to CSS text-decoration-inset Property

Week 4 Jan 19 – Jan 25

This week I learned Promise.try() and Promise.withResolvers().

Promise.try() can catch errors from synchronous execution or asynchronous operations returning a Promise. However, try...catch() has a small problem: if there are asynchronous operations inside, such as setTimeout or inside a Promise, those errors cannot be caught.

Promise.withResolvers() is a new static method added in ECMAScript 2024. Its core function is to decouple the creation of a Promise from its state control (resolve and reject), allowing developers to simultaneously obtain a new Promise instance and the functions bound to it for controlling its state.

More content at: Quick Overview of Promise.try() and Promise.withResolvers()

Week 5 Jan 26 – Feb 1

This week I learned the moveBefore API.

The syntax of this API is similar to the previous insertBefore, with the difference being:

Therefore, moveBefore can preserve the element's current animation state, interaction state, toggle state, etc.

At the same time, moveBefore is also related to Web Components development. When the connectedMoveCallback lifecycle function is set, the disconnectedCallback() and connectedCallback() lifecycle functions will not execute.

See my article for details: Goodbye insertBefore, Use moveBefore to Move DOM Elements

Week 6 Feb 2 – Feb 8

This week I learned the CSS text-box property.

In the traditional CSS box model, text line-height creates extra "half-leading" space above and below the text.

This makes it difficult to precisely align text with adjacent icons or container edges.

Using the text-box property allows you to:

However, in my own practice, the CSS text-box property cannot solve the vertical alignment problem of inline elements.

For specific details, refer to: What is the CSS text-box Property Used For?

Week 7 Feb 9 – Feb 15 ~ Week 8 Feb 16 – Feb 22

It's Chinese New Year! Why study? Let's have fun together! ♫ ♬ ♪ ♩ ♭ ♪

Week 9 Feb 23 – Mar 1

I only recently learned that JS regex, besides global g, case-insensitive i, and multiline m, also supports a flag called y.

It represents sticky matching, which is particularly suitable for processing long texts with structural patterns.

More content in this article: Sticky Matching with the JS Regex y Flag

Week 10 Mar 2 – Mar 8

This week I learned about the HTML interestfor attribute and hover popover interaction effects.

Previously introduced, the popover attribute allows elements to have click-to-show overlay interactions. Now, there is a native implementation for hover overlay interactions: the interestfor attribute.

It not only supports popover overlays but also non-popover type target elements. Trigger elements can be links in addition to buttons, with accompanying CSS pseudo-classes :interest-source and :interest-target.

These can match the active state of the target element.

For more detailed content, visit my article: HTML interestfor Attribute and Hover Popover Interaction Effects

Week 11 Mar 9 – Mar 15

This week I learned about the newly supported closedBy attribute for the HTML <dialog> element.

Previously, clicking the dark backdrop behind a Dialog modal would not close it.

Now, with the closedBy attribute, we can actively set whether clicking the backdrop overlay closes the dialog.

Currently, both Chrome and Firefox support it. If not supported, it doesn't matter; a Polyfill can be introduced for compatibility.

More content can be found in this article: HTML dialog Element Newly Supports the closedBy Attribute

Week 12 Mar 16 – Mar 22

This week I took a look at the WebTransport API.

This API is hailed as the next-generation web bidirectional communication technology.

While WebSocket can solve most problems, it's not perfect. Issues like head-of-line blocking, single stream transmission only, and disconnection upon network switching make it feel lacking, especially for scenarios demanding extremely low latency like real-time gaming and live streaming.

Hence, the WebTransport API was created, particularly suitable for high-concurrency, low-latency real-time scenarios.

More content in this article: A Brief Study of WebTransport API: Next-Gen Web Bidirectional Communication Technology

Week 13 Mar 23 – Mar 29

This week I learned about CSS corner-shape background pattern technology.

corner-shape can achieve various graphic effects, as shown below:

Is it possible to display these graphics as background patterns?

It turns out it is, using SVG's <foreignObject> element.

Below is an implemented example:

More content can be found in my article: CSS corner-shape and Background Pattern Technology

Week 14 Mar 30 – Apr 5

This week I learned the implementation of CSS hexagonal avatars and honeycomb layouts.

First, the hexagonal avatar:

img {
  aspect-ratio: cos(30deg);
  border-radius: 50% / 25%;
  corner-shape: bevel;
  width: 150px;
  border: 1px solid #0001;
  object-fit: cover;
}

Effect illustration:

Based on this hexagon, we can further implement a honeycomb layout effect:

For the specific implementation, see this article: Implementation of CSS Hexagonal Avatars and Honeycomb Layout

Week 15 Apr 6 – Apr 12

This week I learned about JS WeakRef weak references.

Weak types in the JS language, besides WeakRef introduced in this article, also include WeakMap and WeakSet.

Among them:

WeakMap and WeakSet are collection data structures where weak references are the way they manage members; WeakRef is a wrapper for a weak reference to a single object, allowing you to actively check if the object is still alive.

Explained in more colloquial terms:

Although WeakRef can optimize memory overhead and seems very valuable, both the official documentation and I personally recommend using it cautiously. Why is that?

See the article for details: Be Sure to Use JS WeakRef Cautiously

Week 16 Apr 13 – Apr 19

This week I pre-researched using mediabunny to implement video watermarking, clipping, compositing, and other functions purely in JS. Previously, development used the native WebCodecs API. Although more technically sophisticated, the code was profound and unfriendly for colleagues taking over the project.

Recently encountering similar requirements, I decided to use a mature utility library: mediabunny.

Indeed, the business code is much cleaner.

See details: Using mediabunny to Implement Video Watermarking, Clipping, Compositing, etc. in Pure JS

Week 17 Apr 20 – Apr 26

This week I learned a very interesting CSS trick: how to use CSS to determine from which direction the mouse enters an element?

As shown below, if the mouse enters from below, a smiley face; if from above, a sad face.

The principle is simple:

Create a 50% height overlay covering the .face element. If the user's mouse first touches this overlay upon entry, it matches .face-x:hover:not(:has(.face:hover)). If entering from another direction, without the overlay blocking, it matches .face-x:has(.face:hover).

If the former matches, quickly expand the overlay's size to cover the entire container element; if the latter matches, quickly hide the overlay.

This way, the two matching states won't conflict.

For implementation source code and a more detailed explanation, see: How to Use CSS to Determine Mouse Entry Direction?

Week 18 Apr 27 – May 3

This week I learned the JSON.rawJSON method.

In front-end development, the most commonly used methods of the JSON object are parse and stringify. We deal with them almost daily—using parse to analyze data after API requests, and stringify to serialize objects before submitting data.

Everyone knows that numbers in JavaScript are all floating-point numbers, which means some super-large integers cannot be accurately represented. For example, if we have a very large ID value: 12345678901234567890, when we serialize it using stringify, we find a strange problem: the digits at the end are automatically "rounded off," and precision is directly lost!

This is not a bug, but an inherent flaw of JavaScript floating-point numbers—it cannot accurately represent all integers. When a number exceeds 2^53, precision deviation occurs.

JSON.rawJSON can solve this problem.

Besides this, JSON.rawJSON can also precisely control the JSON serialization format.

More content at: What is the Purpose of the JSON.rawJSON Method?

Week 19 May 4 – May 10

This week's learning content was attempting to use pretext to achieve a text wrapping effect on all four sides.

If interested, visit here to learn more: pretext and Implementation of Four-Sided Text Wrapping Effect

Week 20 May 11 – May 17

This week I learned the CSS caret-shape property.

The previous caret-color property allowed us to define the color of the cursor. Now, the cursor's shape can also be set, along with controlling whether the cursor blinks.

See this article for details: The Cursor Shape Can Now Be Set: The CSS caret-shape Property

Week 21 May 18 – May 24

This week I learned the text-align: match-parent declaration.

This feature was actually introduced in "CSS New World".

Its literal purpose is to inherit the parent element's alignment. Actually, this literal purpose is quite strange.

Because text-align itself has inheritance characteristics. In reality, its effect is reflected in the acquisition of computed values.

When a parent element is set to text-align: end, by default, the child element's textAlign computed value will be end.

However, end could be on the left or the right (controlled by the direction property).

If we want to know the precise left or right, we need to use text-align: match-parent.

See this article for details: Quickly Understand text-align match-parent Declaration in 1 Minute

Week 22 May 25 – May 31

Following the preventScroll parameter, the JS focus() method has added a new optional parameter called focusVisible, used to control whether the focus outline is displayed after a control element is triggered by the focus() method.

A feature related to accessibility details.

See this article for details: New Feature Express: focus() Behavior Adds focusVisible Control

Week 23 Jun 1 – Jun 7

CSS finally has a function that can automatically match color contrast ratios. This is particularly useful in the field of accessibility; foreground and background colors can now be automatically adapted.

This function is the CSS contrast-color() function.

This function can return white or black based on the passed-in color value (according to contrast ratio).

Currently, all major browsers support it:

See this article for details: Introduction to CSS contrast-color() Function

Week 24 Jun 8 – Jun 14

This week I learned the brand-new CSS border-shape property.

border-shape allows an element's border box to be any regular or irregular shape.

For example:

<style>
  .star {
    width: 150px;
    aspect-ratio: 1.076;
    border: dashed red;
    border-shape: shape(from 50% 0%,line to 62.39% 37.51%,line to 100% 37.51%,line to 69.85% 61.58%,line to 80.88% 100%,line to 50% 76.84%,line to 19.12% 100%,line to 30.15% 61.58%,line to 0% 37.51%,line to 37.61% 37.51%,close);
    box-shadow: 2px 2px 4px #0008;
    background: lightyellow;
  }
</style>
<canvas class="star"></canvas>

At this point, you can get the rendering effect shown in the screenshot below:

This is another powerful tool in the field of CSS graphics rendering. However, compatibility is currently not great; only Chrome supports it. But for unsupported browsers, you can use clip-path + drop-shadow() filter (tags need to be nested) for approximate simulation.

See this article for details: Introduction to the Brand-New CSS border-shape Property

Week 25 Jun 15 – Jun 21

This week I learned the HTML command attribute and the JS toggle event.

The HTML command attribute can only be set on button elements and can trigger the element's built-in methods. For example:

<button commandfor="my-dialog" command="show-modal">
  Click to show dialog
</button>

<dialog id="my-dialog" closedby="any">
  I'm displayed!
</dialog>

The <dialog> element has a built-in showModal method. At this point, clicking the button will display the dialog.

The ToggleEvent event type is also a new feature, triggered after a Popover or <dialog> element is shown or hidden.

It includes event object properties like newState and oldState, allowing you to determine the current expanded or collapsed state of the element.

See this article for details: All Good Stuff! HTML command Attribute and JS toggle Event

Week 26 Jun 22 – Jun 28

This week I learned the CSS color-scheme property and the light-dark() color function.

light-dark() is a CSS function that accepts two colors or two images and returns one color or image based on the current page's color scheme, without needing prefers-color-scheme media query matching.

prefers-color-scheme can match whether the system-level setting is dark mode or light mode.

This media query was well-intentioned in design, but in practical development, it's rather useless.

Why? It's simple: only advanced users set dark mode or light mode at the system level. For client-side software (web pages included), a user-experience-friendly interaction method should be to set it directly within the current application.

The color-scheme property can change the color scheme of browser built-in components on a web page.

Paired with the light-dark() CSS function, it can truly achieve fully customizable dark/light color scheme capabilities.

See this article for details: CSS color-scheme Property and light-dark() Color Function

Alright, the above is what I learned in the first half of this year, mainly new features.

As for why I still learn these things in the age of AI programming, you can read my article: In the AI Era, Why Am I Still Learning Front-End Fundamentals?

(End)