23 Jan 2024, 18:00:19 HKT

4 Useful CSS & JS Snippets for Web Development

A screen containing HTML code

Before I start my first post, I would like to thank everyone who plays a visit to my blog. Hope you enjoy it!

When I was developing this blog, I came across serval techniques that are new to me and perhaps also useful for future projects. Here I gathered four of them to share, let's check it out!

CSS

:is() Pseudo-class Function

The :is() function is particularly useful when you have to select a large number of elements that are deeply nested.

Suppose we would like the hide a button inside a div when the div is in one of the three states (loading, ended, error):

css
div.loading > button {
  display: none;
}

div.ended > button {
  display: none;
}

div.error > button {
  display: none;
}

The above example works very well, but we can simplify it using the :is() function:

css
div:is(.ended, .error, .loading) > button {
  display: none;
}

We've grouped the three declarations into one! So what is happing here? The :is() function selects any div that matches either selectors inside the brackets, i.e. expanding into div.ended ; div.error and div.loading. It is just like how we do polynomial expansion -- distributing div into the "polynomial" inside the brackets.

:is() function can also be used in multiple layers, the polynomial metaphor still applies. Check out MDN for more examples!

color-mix Function

As its name suggests, the color-mix function mixes two colours based on a specified ratio:

css
color-mix(in srgb, #90caf9 20%, transparent 80%);

In the above example, color-mix mixes 20% of ice-blue (#90caf9) with 80% transparent, resulting a highly transparent ice-blue.

This function is very handy if you want to create a colour dynamically, for example one of the colours is defined through an user-provided variable:

css
/* --text-color could be dynamically changed by JS */
color-mix(in srgb, var(--text-color) 80%, white);

Visit MDN for more examples!

Javascript

Date.toLocaleString()

When it comes to displaying/ formatting date-related information like publish date etc, you may think the of moment.js library. Yet, Date actually comes with a built-in method toLocaleString(locale, options) that can format date into various styles:

typescript
let formattedString = new Date('January 1, 2024 13:00:00')
  .toLocaleString('en-HK', {
      dateStyle: 'medium',
      timeStyle: 'long',
      hour12: false,
      timeZone: 'Asia/Hong_Kong',
    });

// Logs: '1 Jan 2024 at 13:00:00 HKT'
console.log(formattedString)

With toLocaleString() you can format your date into different languages like German by setting locale to de-DE and styles like displaying date in a longer format: 1 January 2024, instead of 1 Jan 2024, can be specified using the dateStyle: 'long' option:

typescript
let formattedString = new Date('January 1, 2024 13:00:00')
  .toLocaleString('de-DE', {
      dateStyle: 'long',
      timeStyle: 'long',
      hour12: false,
      timeZone: 'Asia/Hong_Kong',
    });

// Logs: '1. Januar 2024 um 13:00:00 GMT+8'
console.log(formattedString)

MDN provides a useful reference on how to use this method.

DOMParser

Want to get a specific HTML element from a fetch response? DOMParser.parseFromString() is here to help. It can parse HTML and XML and return HTMLDocument or XMLDocument. This means you can easily select elements using querySelector() or getElementById(), etc:

typescript
let responseText = await fetch('https://example.com').then((response) => response.text());
let parsedDOM = new DOMParser().parseFromString(responseText, 'text/html');

// Logs: 'Example Domain' if not blocked by CORS
console.log(parsedDOM.querySelector('h1').innerText);

It is worth note that <script> tags parsed by parseFromString() is marked as disabled and will not execute. You will need to copy src, type and its textContent (or any other attributes) manually to another script tag that is not marked as disabled, e.g. a script tag created by document.createElement('script').

That's all for my first post! Thanks for reading. If you find any mistakes in this post, feel free to tell me!