Tuesday, February 11, 2025
HomeCSSCompiling CSS With Vite And Lightning CSS

Compiling CSS With Vite And Lightning CSS


Suppose you observe CSS function growth as carefully as we do right here at CSS-Tips. In that case, you could be like me and keen to make use of many of those wonderful instruments however discover browser help generally lagging behind what is likely to be thought of “fashionable” CSS (no matter meaning).

Even when browser distributors all have a sure function launched, customers won’t have the newest variations!

We will definitely plan for this various methods:

  • function detection with @helps
  • progressively enhanced designs
  • polyfills

For even further assist, we flip to construct instruments. Chances are high, you’re already utilizing some form of construct device in your tasks in the present day. CSS builders are probably aware of CSS pre-processors (equivalent to Sass or Much less), however when you don’t know, these are instruments able to compiling many CSS information into one stylesheet. CSS pre-processors assist make organizing CSS loads simpler, as you possibly can transfer elements of CSS into associated folders and import issues as wanted.

Pre-processors don’t simply present organizational superpowers, although. Sass gave us a loopy record of options to work with, together with:

  • extends
  • capabilities
  • loops
  • mixins
  • nesting
  • variables
  • …extra, in all probability!

For some time, this huge function set offered a method of filling gaps lacking from CSS, making Sass (or no matter preprocessor you fancy) really feel like a necessity when beginning a brand new venture. CSS has advanced loads because the launch of Sass — now we have so lots of these options in CSS in the present day — so it doesn’t fairly really feel that manner anymore, particularly now that now we have native CSS nesting and customized properties.

Together with CSS pre-processors, there’s additionally the idea of publish-processing. Any such device often helps rework compiled CSS in several methods, like auto-prefixing properties for various browser distributors, code minification, and extra. PostCSS is the large one right here, providing you with tons of the way to govern and optimize your code, one other step within the construct pipeline.

In lots of implementations I’ve seen, the construct pipeline usually runs roughly like this:

  1. Generate static property
  2. Construct utility information
  3. Bundle for deployment

CSS is often dealt with in that first half, which incorporates operating CSS pre- and post-processors (although post-processing may additionally occur after Step 2). As talked about, the continued evolution of CSS makes it much less obligatory for a device equivalent to Sass, so we’d have a chance to avoid wasting time.

Vite for CSS

Awarded “Most Adopted Expertise” and “Most Liked Library” from the State of JavaScript 2024 survey, Vite definitely appears to be one of many extra common construct instruments accessible. Vite is principally used to construct reactive JavaScript front-end frameworks, equivalent to Angular, React, Svelte, and Vue (made by the identical developer, after all). Because the identify implies, Vite is loopy quick and may be as easy or advanced as you want it, and has develop into considered one of my favourite instruments to work with.

Vite is generally considered a JavaScript device for JavaScript tasks, however you need to use it with out writing any JavaScript in any respect. Vite works with Sass, although you continue to want to put in Sass as a dependency to incorporate it within the construct pipeline. However, Vite additionally routinely helps compiling CSS with no further steps. We will arrange our CSS code how we see match, with no or very minimal configuration obligatory. Let’s verify that out.

We shall be utilizing Node and npm to put in Node packages, like Vite, in addition to instructions to run and construct the venture. When you should not have node or npm put in, please try the obtain web page on their web site.

Navigate a terminal to a protected place to create a brand new venture, then run:

npm create vite@newest

The command line interface will ask a couple of questions, you possibly can maintain it so simple as doable by selecting Vanilla and JavaScript which is able to give you a starter template together with some no-frameworks-attached HTML, CSS, and JavaScript information to assist get you began.

terminal displaying the output of running the command npm create vite@latest

Earlier than operating different instructions, open the folder in your IDE (built-in growth setting, equivalent to VSCode) of alternative in order that we are able to examine the venture information and folders.

If you want to observe together with me, delete the next information which can be pointless for demonstration:

  • property/
  • public/
  • src/
  • .gitignore

We must always solely have the next information left in out venture folder:

VSCode file browser display two files: index.html and package.json

Let’s additionally exchange the contents of index.html with an empty HTML template:

<!doctype html>

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta identify="viewport" content material="width=device-width, initial-scale=1.0" />
	
    <title>CSS Solely Vite Challenge</title>
  </head>
  <physique>
    <!-- empty for now -->
  </physique>
</html>

One final piece to arrange is Vite’s dependencies, so let’s run the npm set up command:

npm set up
terminal displaying the output of running the command npm install

A brief sequence will happen within the terminal. Then we’ll see a brand new folder known as node_modules/ and a package-lock.json file added in our file viewer.

  • node_modules is used to deal with all bundle information put in by means of node bundle supervisor, and permits us to import and use put in packages all through our functions.
  • package-lock.json is a file often used to verify a growth group is all utilizing the identical variations of packages and dependencies.
VSCode file browser displaying a node_modules folder, index.html file, package-lock.json file, and a package.json file

We probably received’t want to the touch this stuff, however they’re obligatory for Node and Vite to course of our code in the course of the construct. Contained in the venture’s root folder, we are able to create a types/ folder to include the CSS we’ll write. Let’s create one file to start with, major.css, which we are able to use to check out Vite.

├── public/
├── types/
|   └── major.css
└──index.html

In our index.html file, contained in the <head> part, we are able to embody a <hyperlink> tag pointing to the CSS file:

<head>
  <meta charset="UTF-8" />
  <hyperlink rel="icon" kind="picture/svg+xml" href="https://css-tricks.com/vite.svg" />
  <meta identify="viewport" content material="width=device-width, initial-scale=1.0" />
	
  <title>CSS Solely Vite Challenge</title>

  <!-- Primary CSS -->
  <hyperlink rel="stylesheet" href="https://css-tricks.com/compiling-css-with-vite-and-lightning-css/types/major.css">
</head>

Let’s add a little bit of CSS to major.css:

physique {
  background: inexperienced;
}

It’s not a lot, however it’s all we’ll want in the meanwhile! In our terminal, we are able to now run the Vite construct command utilizing npm:

npm run construct

With every thing linked up correctly, Vite will construct issues based mostly on what is out there throughout the index.html file, together with our linked CSS information. The construct shall be very quick, and also you’ll be returned to your terminal immediate.

Terminal displaying the output of the command npm run build, including the filesizes of compiled files
Vite will present a quick report, showcasing the file sizes of the compiled venture.

The newly generated dist/ folder is Vite’s default output listing, which we are able to open and see our processed information. Trying out property/index.css (the filename will embody a singular hash for cache busting), and also you’ll see the code we wrote, minified right here.

VSCode editor displaying a minified CSS file

Now that we all know easy methods to make Vite conscious of our CSS, we’ll in all probability need to begin writing extra CSS for it to compile.

As fast as Vite is with our code, continuously re-running the construct command would nonetheless get very tedious. Fortunately, Vite gives its personal growth server, which features a stay setting with scorching module reloading, making modifications seem immediately within the browser. We will begin the Vite growth server by operating the next terminal command:

npm run dev
Vite development server running in a terminal

Vite makes use of the default community port 5173 for the event server. Opening the http://localhost:5137/ tackle in your browser will show a clean display screen with a inexperienced background.

Arc browser window, navigated to http://localhost:5173, a blank page with a green background

Including any HTML to the index.html or CSS to major.css, Vite will reload the web page to show modifications. To cease the event server, use the keyboard shortcut CTRL+C or shut the terminal to kill the method.

At this level, you just about know all you should learn about easy methods to compile CSS information with Vite. Any CSS file you hyperlink up shall be included within the constructed file.

Organizing CSS into Cascade Layers

One of many objects on my 2025 CSS Wishlist is the power to apply a cascade layer to a hyperlink tag. To me, this is likely to be useful to prepare CSS in a significant methods, in addition to superb management over the cascade, with the advantages cascade layers present. Sadly, this can be a fairly troublesome ask when contemplating the way in which browsers paint types within the viewport. Any such performance is being mentioned between the CSS Working Group and TAG, however it’s unclear if it’ll transfer ahead.

With Vite as our construct device, we are able to replicate the idea as a method to arrange our constructed CSS. Contained in the major.css file, let’s add the @layer at-rule to set the cascade order of our layers. I’ll use a few layers right here for this demo, however be at liberty to customise this setup to your wants.

/* types/major.css */
@layer reset, layouts;

That is all we’ll want inside our major.css, let’s create one other file for our reset. I’m a fan of my buddy Mayank‘s fashionable CSS reset, which is out there as a Node bundle. We will set up the reset by operating the next terminal command:

npm set up @acab/reset.css
Terminal displaying the output of running npm install @acab/reset.css

Now, we are able to import Mayank’s reset into our newly created reset.css file, as a cascade layer:

/* types/reset.css */
@import '@acab/reset.css' layer(reset);

If there are some other reset layer stylings we need to embody, we are able to open up one other @layer reset block inside this file as effectively.

/* types/reset.css */
@import '@acab/reset.css' layer(reset);

@layer reset {
  /* customized reset types */
}

This @import assertion is used to tug packages from the node_modules folder. This folder just isn’t usually accessible within the constructed, public model of a web site or utility, so referencing this may trigger issues if not dealt with correctly.

Now that now we have two information (major.css and reset.css), let’s hyperlink them up in our index.html file. Contained in the <head> tag, let’s add them after <title>:

<head>
  <meta charset="UTF-8" />
  <hyperlink rel="icon" kind="picture/svg+xml" href="https://css-tricks.com/vite.svg" />
  <meta identify="viewport" content material="width=device-width, initial-scale=1.0" />
	
  <title>CSS Solely Vite Challenge</title>
	
  <hyperlink rel="stylesheet" href="https://css-tricks.com/compiling-css-with-vite-and-lightning-css/types/major.css">
  <hyperlink rel="stylesheet" href="https://css-tricks.com/compiling-css-with-vite-and-lightning-css/types/reset.css">
</head>

The concept right here is we are able to add every CSS file, within the order we want them parsed. On this case, I’m planning to tug in every file named after the cascade layers setup in the principle.css file. This will not work for each setup, however it’s a useful manner to bear in mind the priority of how cascade layers have an effect on computed types when rendered in a browser, in addition to grouping equally related information.

Since we’re within the index.html file, we’ll add a 3rd CSS <hyperlink> for types/layouts.css.

<head>
  <meta charset="UTF-8" />
  <hyperlink rel="icon" kind="picture/svg+xml" href="https://css-tricks.com/vite.svg" />
  <meta identify="viewport" content material="width=device-width, initial-scale=1.0" />
	
  <title>CSS Solely Vite Challenge</title>
	
  <hyperlink rel="stylesheet" href="https://css-tricks.com/compiling-css-with-vite-and-lightning-css/types/major.css">
  <hyperlink rel="stylesheet" href="https://css-tricks.com/compiling-css-with-vite-and-lightning-css/types/reset.css">
  <hyperlink rel="stylesheet" href="https://css-tricks.com/compiling-css-with-vite-and-lightning-css/types/layouts.css">
</head>

Create the types/layouts.css file with the brand new @layer layouts declaration block, the place we are able to add layout-specific stylings.

/* types/layouts.css */
@layer layouts {
  /* layouts types */
}

For some fast, simple, and superior CSS snippets, I are inclined to discuss with Stephanie EcklesSmolCSS venture. Let’s seize the “Smol intrinsic container” code and embody it throughout the layouts cascade layer:

/* types/layouts.css */
@layer layouts {
  .smol-container {
    width: min(100% - 3rem, var(--container-max, 60ch));
    margin-inline: auto;
  }
}

This highly effective little, two-line container makes use of the CSS min() operate to supply a responsive width, with margin-inline: auto; set to horizontally heart itself and include its youngster components. We will additionally dynamically alter the width utilizing the --container-max customized property.

Now if we re-run the construct command npm run construct and verify the dist/ folder, our compiled CSS file ought to include:

  • Our cascade layer declarations from major.css
  • Mayank’s CSS reset absolutely imported from reset.css
  • The .smol-container class added from layouts.csss

As you possibly can see, we are able to get fairly far with Vite as our construct device with out writing any JavaScript. Nevertheless, if we select to, we are able to prolong our construct’s capabilities even additional by writing only a little bit of JavaScript.

Publish-processing with LightningCSS

Lightning CSS is a CSS parser and post-processing device that has a number of good options baked into it to assist with cross-compatibility amongst browsers and browser variations. Lightning CSS can rework a number of fashionable CSS into backward-compatible types for you.

We will set up Lightning CSS in our venture with npm:

npm set up --save-dev lightningcss

The --save-dev flag means the bundle shall be put in as a growth dependency, because it received’t be included with our constructed venture. We will embody it inside our Vite construct course of, however first, we might want to write a tiny little bit of JavaScript, a configuration file for Vite. Create a brand new file known as: vite.config.mjs and inside add the next code:

// vite.config.mjs
export default {
  css: {
    transformer: 'lightningcss'
  },
  construct: {
    cssMinify: 'lightningcss'
  }
};

Vite will now use LightningCSS to rework and minify CSS information. Now, let’s give it a check run utilizing an oklch coloration. Inside major.css let’s add the next code:

/* major.css */
physique {
  background-color: oklch(51.98% 0.1768 142.5);
}

Then re-running the Vite construct command, we are able to see the background-color property added within the compiled CSS:

/* dist/index.css */
physique {
  background-color: inexperienced;
  background-color: coloration(display-p3 0.216141 0.494224 0.131781);
  background-color: lab(46.2829% -47.5413 48.5542);
}

Lightning CSS converts the colour white offering fallbacks accessible for browsers which could not help newer coloration varieties. Following the Lightning CSS documentation for utilizing it with Vite, we are able to additionally specify browser variations to focus on by putting in the browserslist bundle.

Browserslist will give us a method to specify browsers by matching sure circumstances (attempt it out on-line!)

npm set up -D browserslist

Inside our vite.config.mjs file, we are able to configure Lightning CSS additional. Let’s import the browserslist bundle into the Vite configuration, in addition to a module from the Lightning CSS bundle to assist us use browserlist in our config:

// vite.config.mjs
import browserslist from 'browserslist';
import { browserslistToTargets } from 'lightningcss';

We will add configuration settings for lightningcss, containing the browser targets based mostly on specified browser variations to Vite’s css configuration:

// vite.config.mjs
import browserslist from 'browserslist';
import { browserslistToTargets } from 'lightningcss';

export default {
  css: {
    transformer: 'lightningcss',
    lightningcss: {
      targets: browserslistToTargets(browserslist('>= 0.25%')),
    }
  },
  construct: {
    cssMinify: 'lightningcss'
  }
};

There are many methods to increase Lightning CSS with Vite, equivalent to enabling particular options, excluding options we received’t want, or writing our personal customized transforms.

// vite.config.mjs
import browserslist from 'browserslist';
import { browserslistToTargets, Options } from 'lightningcss';

export default {
  css: {
    transformer: 'lightningcss',
    lightningcss:  Options.Colours,
    
  },
  construct: {
    cssMinify: 'lightningcss'
  }
};

For a full record of the Lightning CSS options, try their documentation on function flags.

Is any of this obligatory?

Studying by means of all this, you could be asking your self if all of that is actually obligatory. The reply: completely not! However I believe you possibly can see the advantages of getting access to partialized information that we are able to compile into unified stylesheets.

I doubt I’d go to those lengths for smaller tasks, nevertheless, if constructing one thing with extra complexity, equivalent to a design system, I’d attain for these instruments for organizing code, cross-browser compatibility, and totally optimizing compiled CSS.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments