CSS, which stands for cascading style sheets, is a styling language used for presenting content on a website.
A style sheet can be included in a web page through various ways; you can embed a <link>
tag that links to an external CSS file, you can embed the styles inline or inside a <style>
block within the <head>
area, or you can use a modern CSS tool like PostCSS to use some extra handy features.
In some cases, however, you might want to use a particular style sheet only if a specified condition is true
. For example, you might want to apply a mobile-friendly style sheet when viewing a site on a mobile device and apply a desktop version when viewing the site on a desktop screen.
In this tutorial, we’ll go over two effective ways, using media queries and PostCSS, to selectively load and apply style sheets as well as review some caveats surrounding each process:
<link>
tag to load style sheetsA media query is a CSS technique used to make a website look good on any screen. It uses the @media
rule to include a block of CSS properties that can be applied only if a condition is true
.
For example, using the @media
rule in CSS, you can write a media query to style your text differently in screens wider than 500px and screens lower than 500px:
/* text is blue on screens smaller than 500px */ @media (max-width: 500px) { p { color: blue; } } /* text is red on screens larger than 500px */ @media (min-width: 500px) { p { color: red; } }
Media queries are commonly written in style sheets, but you can write media queries directly inside your HTML markup, too.
<link>
tag to load style sheetsThe <link>
tag in HTML establishes a link between an HTML document and an external resource, such as an external style sheet.
Though this element can appear multiple times within a document, it only goes into the <head>
section. <link>
is an empty tag, so it can hold multiple attributes that describe to the browser how the linked item relates to the containing document.
When working with complex websites, you can create different CSS files, all tailored to different screen sizes or orientations. Then, using the media
attribute on the <link>
tag, you can set up media queries to load corresponding stylesheets.
Consider the following HTML, for example:
<!DOCTYPE html> <html lang="en"> <head> <title>Document</title> <link rel="stylesheet" media='screen and (max-width: 699px)' href="phone.css"/> <link rel="stylesheet" media='screen and (min-width: 700px)' href="tablet.css"/> </head> <body> <p>Text color: Blue in phones, red in tablets, green in even smaller screens</p> </body> </html>
Here’s the style for phone.css
:
p { color: blue; }
And here’s the style for tablet.css
:
p { color: red; }
On viewports with a width less than 700px, the stylesheet phone.css
will apply to the document, making the text turn blue. When the screen width exceeds 699px, tablet.css
will apply to the document, and the text will become red.
This approach gives you more flexibility when it comes to organizing your stylesheets. So, instead of putting all your styles and media queries inside a single CSS file, you can break them down into different files and load them directly from HTML using media queries.
With HTML media queries, both CSS files are downloaded regardless of whether or not the media query is satisfied. The browser must download all of it so it can reevaluate when orientation changes. However, parsing unwanted CSS by the browser is delayed.
But, with CSS media queries, all style blocks are completely parsed and processed, whether or not the query is satisfied.
When loading a CSS file via HTML <link>
, the style sheet may contain a media query of its own.
To demonstrate this, we’ll nest another media query inside of phone.css
:
p { color: blue; } /* nested media query */ @media (max-width: 200px) { p { color: green; } }
Here, we’re saying that the text should turn green when the screen width is less than 200px. When our browser resizes to take up a width of 200px or less, the text turns green.
However, widen the screen to a width higher than 200px, and the text turns back to blue. This demonstrates that the browser will also process any nested media query.
PostCSS provides an extensive plugin ecosystem to help CSS authors improve their CSS writing experience. This includes a plugin that can combine style sheets from different CSS files into a single CSS file.
One way to set up PostCSS in your web project is with the PostCSS CLI, and that’s what we’ll use here. Note, however, that Node and npm are both required to run PostCSS, so ensure you have them installed first.
To begin, let’s create an empty postcss-demo
folder, then cd
into the folder and initialize a fresh node project by running npm init -y
from the command line. This generates a package.json file in our postcss-demo
folder with default values.
Now, to install PostCSS, the PostCSS CLI, and the PostCSS imports plugin all in one go and save them as dependencies, use this command:
npm i -D postcss postcss-cli postcss-import
PostCSS uses the PostCSS import plugin to bundle together different style sheets from different sources into a single CSS file.
For example, inside the postcss-demo/src
folder, we can decide to group our style sheets into different folders based on what they do.
Style sheets that reset the document go into the base folder, style sheets that design common UI components (for example, button.css
for buttons, card.css
for cards, and form.css
for forms) go into the components folder, and so on.
Basically, you can organize your stylesheets however you want to.
Then, with a couple of configuration settings and CLI commands, we can bring in all these CSS files we need into one single CSS file for production.
For reference, here’s the structure of our project at this point:
postcss-demo ├── src │ ├── base │ ├── base.css │ ├── reset.css │ ├── components │ ├── button.css │ ├── card.css │ ├── form.css │ ├── utilities │ ├── container.css │ ├── margin.css │ ├── padding.css │ └── style.css ├── node_modules ├── package.json └── package-lock.json
Now that we installed all our dependencies, we must set up a PostCSS config file.
To do this, create a postcss.config.js
file directly in postcss-demo
(root folder).
Inside this file, we’ll register the plugin so we can use it:
module.exports = { plugins: [ require('postcss-import'), ] }
Next, inside of the postcss-demo/src/style.css
file , we are going to instruct PostCSS on what stylesheets to import using the @import
directive:
@import 'base/base.css'; @import 'base/reset.css'; @import 'components/button.css'; @import 'components/card.css'; @import 'components/form.css'; @import 'utilities/container.css'; @import 'utilities/padding.css'; @import 'utilities/margin.css';
Here, we specified the relative paths to all the style sheets that we want to import.
With the directives and the paths all in place, let’s import these different style sheets into styles.css
. To do that, open the package.json
file and include the following script under scripts
:
{ // "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "postcss:watch": "postcss src/style.css --dir public" }, // }
Here, we specify what to do when the script postcss:watch
runs. In addition to running postcss
, we tell it to go into our src
folder, find the styles.css
file, and then we specified what directory to output the combined style sheets into.
Finally, run the following script:
npm run postcss:watch
Upon successful execution, the script generates a public folder with the file style.css
. This file contains all the style sheets previously imported into src/style.css
.
Therefore, any stylesheet imported into src/styles.css
outputs to public/style.css
.
In this tutorial, we discussed in detail two ways to load CSS into a webpage by covering media queries and Post CSS imports.
Media queries can be written both inside CSS and HTML. Inside HTML, the <link>
tag must be provided with a media
attribute containing the media query and the URL link to the external CSS file, which applies when the query condition is true
.
PostCSS, however, uses a special import plugin to bundle together disparate CSS files into one single CSS file.
If you have any questions related to this topic, please let me know in the comments.
Have a great week!
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
Modernize how you debug web and mobile apps — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.
Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.