Media queries — hidden gems

Wojciech Trawiński
JavaScript everyday
3 min readMay 29, 2024
Photo by Luca Micheli on Unsplash

As a frontend developer, you’ve probably used media queries in CSS to create responsive user interfaces. This robust feature allows you to adjust your layout dynamically based on different factors, most commonly viewport dimensions.

In the rapidly changing world of web development, it’s easy to overlook the newest additions that could transform your workflow. Let’s explore!

Consider the following media query:

@media (min-width: 768px) and (max-width: 1024px) {
.container {
display: flex;
}
}

You can enhance readability by utilizing range syntax operators:

@media (768px <= width <= 1024px) {
.container {
display: flex;
}
}

Next, you can utilize the nesting capabilities of CSS to keep declarations within the scope of the selector:

before:

.container {
background-color: green;

/* other CSS declarations */
}

/* other CSS rules */

@media (768px <= width <= 1024px) {
.container {
display: flex;
}
}

now:

.container {
background-color: green;

/* other CSS declarations */

@media (768px <= width <= 1024px) {
display: flex;
}
}

/* other CSS rules */

Finally, it’s important to remember that media queries are not just about adhering to viewport dimensions, but also about targeting various conditions represented by media features.

Here are a few that I find particularly valuable.

prefers-color-scheme

It allows to support dark mode based on device system preferences:

:root {
@media (prefers-color-scheme: light) {
--background-color: #fff;
--text-color: #000;
}

@media (prefers-color-scheme: dark) {
--background-color: #000;
--text-color: #fff;
}
}

body {
background-color: var(--background-color);
color: var(--text-color);
}

You can find more information about it here 👇

If you want to fully support dark mode, consider reading one of my previous blog posts 👇

prefers-reduced-motion

Users can choose to opt out of excessive movement effects at the system level, similar to how they switch between light and dark modes. This preference can also be respected:

.container {
animation: 1s linear slidein;

/* other CSS declarations */

@media (prefers-reduced-motion: reduce) {
animation: none;
}
}

@keyframes slidein {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}

You can find more information about it here 👇

pointer

Consider the user’s primary input mechanism, whether it’s a keyboard, mouse, or imprecise finger. For instance, you might increase the tap target size by adjusting the padding when your application is accessed on a mobile phone or any other device lacking a precise input mechanism:

.add-to-cart-btn {
padding: 8px;

@media (pointer: coarse) {
padding: 12px;
}
}

You can find more information about it here 👇

hover

You can determine if the user’s primary input mechanism supports the hover state and adjust the user interface accordingly. For example, you might apply different styles only if the hover state is fully supported:

.add-to-cart-btn {
background-color: green;

@media (hover: hover) {
&:hover {
background-color: yellow;
}
}
}

You can find more information about it here 👇

scripting

You can now test if JavaScript (JS) is enabled and, for instance, hide certain user interface elements that require JS:

.play-game-btn {
@media (scripting: none) {
display: none;
}
}

You can find more information about it here 👇

It’s worth noting that you can easily emulate media feature values using Chrome DevTools:

The web development world changes rapidly, so it’s essential to stay updated with new additions. These updates can enhance the developer experience with more concise and readable syntax or improve user experience by considering user preferences and interaction modes.

I hope you liked my story, thanks for reading! 🙂

--

--