Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
@vanilla-extract/webpack-plugin
Advanced tools
@vanilla-extract/webpack-plugin is a plugin for integrating vanilla-extract with Webpack. Vanilla-extract is a CSS-in-TypeScript library that allows you to write type-safe, locally scoped styles. This plugin helps in compiling and bundling these styles efficiently with Webpack.
Basic Setup
This code demonstrates how to set up the @vanilla-extract/webpack-plugin in a Webpack configuration. It includes the necessary rules and plugins to process .css.ts files.
{"webpack.config.js":"const { VanillaExtractPlugin } = require('@vanilla-extract/webpack-plugin');\n\nmodule.exports = {\n module: {\n rules: [\n {\n test: /\\.css\\.ts$/,\n use: [\n 'style-loader',\n 'css-loader',\n '@vanilla-extract/webpack-plugin/loader'\n ]\n }\n ]\n },\n plugins: [\n new VanillaExtractPlugin()\n ]\n};"}
Using with TypeScript
This code sample shows how to create a style using vanilla-extract in a TypeScript file. The `style` function is used to define CSS properties.
{"styles.css.ts":"import { style } from '@vanilla-extract/css';\n\nexport const myClass = style({\n backgroundColor: 'blue',\n color: 'white',\n padding: '10px'\n});"}
Theming Support
This code demonstrates how to create a theme using vanilla-extract. The `createTheme` function is used to define theme variables that can be used throughout your application.
{"theme.css.ts":"import { createTheme } from '@vanilla-extract/css';\n\nexport const [themeClass, vars] = createTheme({\n color: {\n primary: 'blue',\n secondary: 'green'\n },\n font: {\n body: 'Arial, sans-serif'\n }\n});"}
styled-components is a popular library for writing CSS-in-JS. It allows you to style your components using tagged template literals. Unlike vanilla-extract, styled-components generates styles at runtime and supports dynamic styling based on props.
Emotion is another CSS-in-JS library that offers both runtime and compile-time styling. It provides a similar developer experience to styled-components but with additional features like zero-runtime CSS extraction. Emotion's compile-time approach is somewhat similar to vanilla-extract, but it also supports runtime styling.
Linaria is a zero-runtime CSS-in-JS library that extracts styles to CSS files at build time. This is similar to vanilla-extract's approach of generating static CSS. Linaria allows you to write styles using tagged template literals and ensures that no CSS is generated at runtime.
Zero-runtime Stylesheets-in-TypeScript.
Write your styles in TypeScript (or JavaScript) with locally scoped class names and CSS Variables, then generate static CSS files at build time.
Basically, itโs โCSS Modules-in-TypeScriptโ but with scoped CSS Variables + heaps more.
๐ง ย Please note, this is an alpha release.
๐ฅ ย All styles generated at build time โ just like Sass, Less, etc.
โจ ย Minimal abstraction over standard CSS.
๐ฆ ย Works with any front-end framework โ or even without one.
๐ณ ย Locally scoped class names โ just like CSS Modules.
๐ ย Locally scoped CSS Variables, @keyframes
and @font-face
rules.
๐จ ย High-level theme system with support for simultaneous themes. No globals!
๐ ย Utils for generating variable-based calc
expressions.
๐ช ย Type-safe styles via CSSType.
๐โโ๏ธ ย Optional runtime version for development and testing.
๐ ย Optional API for dynamic runtime theming.
Write your styles in .css.ts
files.
// styles.css.ts
import { createTheme, style } from '@vanilla-extract/css';
export const [themeClass, themeVars] = createTheme({
color: {
brand: 'blue'
},
font: {
body: 'arial'
}
});
export const exampleStyle = style({
backgroundColor: themeVars.color.brand,
fontFamily: themeVars.font.body,
color: 'white',
padding: 10
});
๐ก These
.css.ts
files will be evaluated at build time. None of the code in these files will be included in your final bundle. Think of it as using TypeScript as your preprocessor instead of Sass, Less, etc.
Then consume them in your markup.
// app.ts
import { themeClass, exampleStyle } from './styles.css.ts';
document.write(`
<section class="${themeClass}">
<h1 class="${exampleStyle}">Hello world!</h1>
</section>
`);
There are currently a few integrations to choose from.
$ yarn add --dev @vanilla-extract/css @vanilla-extract/babel-plugin @vanilla-extract/webpack-plugin
{
"plugins": ["@vanilla-extract/babel-plugin"]
}
const { VanillaExtractPlugin } = require('@vanilla-extract/webpack-plugin');
module.exports = {
plugins: [new VanillaExtractPlugin()],
};
const { VanillaExtractPlugin } = require('@vanilla-extract/webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new VanillaExtractPlugin(),
new MiniCssExtractPlugin()
],
module: {
rules: [
{
test: /\.css$/i,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
],
},
],
},
};
$ yarn add --dev @vanilla-extract/css @vanilla-extract/esbuild-plugin
const { vanillaExtractPlugin } = require('@vanilla-extract/esbuild-plugin');
require('esbuild').build({
entryPoints: ['app.ts'],
bundle: true,
plugins: [vanillaExtractPlugin()],
outfile: 'out.js',
}).catch(() => process.exit(1))
Please note: There are currently no automatic readable class names during development. However, you can still manually provide a debug ID as the last argument to functions that generate scoped styles, e.g.
export const className = style({ ... }, 'className');
To add to your Gatsby site, use the gatsby-plugin-vanilla-extract plugin.
๐ฌ If you're a treat user, check out our migration guide.
Creates styles attached to a locally scoped class name.
import { style } from '@vanilla-extract/css';
export const className = style({
display: 'flex'
});
CSS Variables, simple pseudos, selectors and media/feature queries are all supported.
import { style } from '@vanilla-extract/css';
export const className = style({
display: 'flex',
vars: {
'--global-variable': 'purple'
},
':hover': {
color: 'red'
},
selectors: {
'&:nth-child(2n)': {
background: '#fafafa'
}
},
'@media': {
'screen and (min-width: 768px)': {
padding: 10
}
},
'@supports': {
'(display: grid)': {
display: 'grid'
}
}
});
Selectors can also contain references to other scoped class names.
import { style } from '@vanilla-extract/css';
export const parentClass = style({});
export const childClass = style({
selectors: {
[`${parentClass}:focus &`]: {
background: '#fafafa'
}
},
});
๐ก To improve maintainability, each
style
block can only target a single element. To enforce this, all selectors must target the&
character which is a reference to the current element. For example,'&:hover:not(:active)'
is considered valid, while'& > a'
and[`& ${childClass}`]
are not.If you want to target another scoped class then it should be defined within the
style
block of that class instead. For example,[`& ${childClass}`]
is invalid since it targets${childClass}
, so it should instead be defined in thestyle
block forchildClass
.If you want to globally target child nodes within the current element (e.g.
'& > a'
), you should useglobalStyle
instead.
Creates styles attached to a global selector.
import { globalStyle } from '@vanilla-extract/css';
globalStyle('html, body', {
margin: 0
});
Global selectors can also contain references to other scoped class names.
import { globalStyle } from '@vanilla-extract/css';
export const parentClass = style({});
globalStyle(`${parentClass} > a`, {
color: 'pink'
});
Creates an object that maps style names to hashed class names.
๐ก This is useful for mapping to component props, e.g.
<div className={styles.padding[props.padding]}>
import { mapToStyles } from '@vanilla-extract/css';
export const padding = mapToStyles({
small: { padding: 4 },
medium: { padding: 8 },
large: { padding: 16 }
});
You can also transform the values by providing a map function as the second argument.
import { mapToStyles } from '@vanilla-extract/css';
const spaceScale = {
small: 4,
medium: 8,
large: 16
};
export const padding = mapToStyles(spaceScale, (space) => ({
padding: space
}));
Creates a locally scoped theme class and a collection of scoped CSS Variables.
import { createTheme, style } from '@vanilla-extract/css';
export const [themeClass, themeVars] = createTheme({
color: {
brand: 'blue'
},
font: {
body: 'arial'
}
});
You can create theme variants by passing a collection of theme variables as the first argument to createTheme
.
import { createTheme, style } from '@vanilla-extract/css';
export const [themeA, themeVars] = createTheme({
color: {
brand: 'blue'
},
font: {
body: 'arial'
}
});
export const themeB = createTheme(themeVars, {
color: {
brand: 'pink'
},
font: {
body: 'comic sans ms'
}
});
๐ก All theme variants must provide a value for every variable or itโs a type error.
Creates a theme attached to a global selector, but with locally scoped variable names.
import { createGlobalTheme } from '@vanilla-extract/css';
export const themeVars = createGlobalTheme(':root', {
color: {
brand: 'blue'
},
font: {
body: 'arial'
}
});
๐ก All theme variants must provide a value for every variable or itโs a type error.
Creates a collection of CSS Variables without coupling them to a specific theme variant.
๐ก This is useful if you want to split your themes into different bundles. In this case, your themes would be defined in separate files, but we'll keep this example simple.
import {
createThemeVars,
createTheme
} from '@vanilla-extract/css';
export const themeVars = createThemeVars({
color: {
brand: null
},
font: {
body: null
}
});
export const themeA = createTheme(themeVars, {
color: {
brand: 'blue'
},
font: {
body: 'arial'
}
});
export const themeB = createTheme(themeVars, {
color: {
brand: 'pink'
},
font: {
body: 'comic sans ms'
}
});
Assigns a collection of CSS Variables anywhere within a style block.
๐ก This is useful for creating responsive themes since it can be used within
@media
blocks.
import { style, createThemeVars, assignVars } from '@vanilla-extract/css';
export const themeVars = createThemeVars({
space: {
small: null,
medium: null,
large: null
}
});
export const responsiveSpaceTheme = style({
vars: assignVars(themeVars.space, {
small: '4px',
medium: '8px',
large: '16px'
}),
'@media': {
'screen and (min-width: 1024px)': {
vars: assignVars(themeVars.space, {
small: '8px',
medium: '16px',
large: '32px'
})
}
}
});
๐ก All variables passed into this function must be assigned or itโs a type error.
Creates a single CSS Variable.
import { createVar, style } from '@vanilla-extract/css';
export const colorVar = createVar();
export const exampleStyle = style({
color: colorVar
});
Scoped variables can be set via the vars
property on style objects.
import { createVar, style } from '@vanilla-extract/css';
import { colorVar } from './vars.css.ts';
export const parentStyle = style({
vars: {
[colorVar]: 'blue'
}
});
Provides fallback values when consuming variables.
import { createVar, fallbackVar, style } from '@vanilla-extract/css';
export const colorVar = createVar();
export const exampleStyle = style({
color: fallbackVar(colorVar, 'blue');
});
Multiple fallbacks are also supported.
import { createVar, fallbackVar, style } from '@vanilla-extract/css';
export const primaryColorVar = createVar();
export const secondaryColorVar = createVar();
export const exampleStyle = style({
color: fallbackVar(primaryColorVar, secondaryColorVar, 'blue');
});
Creates a custom font attached to a locally scoped font name.
import { fontFace, style } from '@vanilla-extract/css';
const myFont = fontFace({
src: 'local("Comic Sans MS")'
});
export const text = style({
fontFamily: myFont
});
Creates a globally scoped custom font.
import {
globalFontFace,
style
} from '@vanilla-extract/css';
globalFontFace('MyGlobalFont', {
src: 'local("Comic Sans MS")'
});
export const text = style({
fontFamily: 'MyGlobalFont'
});
Creates a locally scoped set of keyframes.
import { keyframes, style } from '@vanilla-extract/css';
const rotate = keyframes({
'0%': { rotate: '0deg' },
'100%': { rotate: '360deg' },
});
export const animated = style({
animation: `3s infinite ${rotate}`;
});
Creates a globally scoped set of keyframes.
import { globalKeyframes, style } from '@vanilla-extract/css';
globalKeyframes('rotate', {
'0%': { rotate: '0deg' },
'100%': { rotate: '360deg' },
});
export const animated = style({
animation: `3s infinite rotate`;
});
We also provide a lightweight standalone package to support dynamic runtime theming.
$ yarn add --dev @vanilla-extract/dynamic
Generates a custom theme at runtime as an inline style object.
import { createInlineTheme } from '@vanilla-extract/dynamic';
import { themeVars, exampleStyle } from './styles.css.ts';
const customTheme = createInlineTheme(themeVars, {
small: '4px',
medium: '8px',
large: '16px'
});
document.write(`
<section style="${customTheme}">
<h1 class="${exampleStyle}">Hello world!</h1>
</section>
`);
Sets a collection of CSS Variables on an element.
import { setElementTheme } from '@vanilla-extract/dynamic';
import { themeVars } from './styles.css.ts';
const element = document.getElementById('myElement');
setElementTheme(element, themeVars, {
small: '4px',
medium: '8px',
large: '16px'
});
๐ก All variables passed into this function must be assigned or itโs a type error.
Sets a single var on an element.
import { setElementVar } from '@vanilla-extract/dynamic';
import { themeVars } from './styles.css.ts';
const element = document.getElementById('myElement');
setElementVar(element, themeVars.color.brand, 'darksalmon');
We also provide a standalone package of optional utility functions to make it easier to work with CSS in TypeScript.
๐ก This package can be used with any CSS-in-JS library.
$ yarn add --dev @vanilla-extract/css-utils
Streamlines the creation of CSS calc expressions.
import { calc } from '@vanilla-extract/css-utils';
const styles = {
height: calc.multiply('var(--grid-unit)', 2)
};
The following functions are available.
calc.add
calc.subtract
calc.multiply
calc.divide
calc.negate
The calc
export is also a function, providing a chainable API for complex calc expressions.
import { calc } from '@vanilla-extract/css-utils';
const styles = {
marginTop: calc('var(--space-large)')
.divide(2)
.negate()
.toString()
};
MIT.
FAQs
Zero-runtime Stylesheets-in-TypeScript
The npm package @vanilla-extract/webpack-plugin receives a total of 3,813 weekly downloads. As such, @vanilla-extract/webpack-plugin popularity was classified as popular.
We found that @vanilla-extract/webpack-plugin demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.ย It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.