The foundation of the UMD Design System, providing design tokens, CSS utilities, and styling patterns that ensure consistent, accessible, and brand-compliant University of Maryland digital experiences.
The UMD Styles Library is the cornerstone of visual consistency across all University of Maryland web properties. It provides a comprehensive collection of design tokens (colors, typography, spacing), utility classes, and CSS-in-JS objects that implement official UMD brand guidelines. This package serves as the single source of truth for styling, enabling developers to build interfaces that are automatically consistent, accessible, and responsive.
# Using npm
npm install @universityofmaryland/web-styles-library
# Using yarn
yarn add @universityofmaryland/web-styles-library
For CSS transformation features:
npm install postcss postcss-js postcss-nesting postcss-discard-duplicates
The simplest way to use the styles library is to import the pre-compiled CSS files directly.
No extra configuration needed—just import in your code:
// In your main entry file (e.g., main.ts)
import '@universityofmaryland/web-styles-library/css/styles.min.css';
Requires css-loader and style-loader (or mini-css-extract-plugin for production):
// In your entry file
import '@universityofmaryland/web-styles-library/css/styles.min.css';
Import only what you need for smaller bundle sizes:
// Critical CSS (load first to prevent FOUT/FOUC)
import '@universityofmaryland/web-styles-library/css/font-faces.min.css';
import '@universityofmaryland/web-styles-library/css/tokens.min.css';
import '@universityofmaryland/web-styles-library/css/base.min.css';
import '@universityofmaryland/web-styles-library/css/typography.min.css';
import '@universityofmaryland/web-styles-library/css/web-components.min.css';
| File | Description | Requires Tokens |
|---|---|---|
styles.min.css |
Full bundle (includes tokens) | No |
tokens.min.css |
CSS custom properties for design tokens | - |
font-faces.min.css |
@font-face rules for all font families | No |
base.min.css |
Root and reset styles | Yes |
typography.min.css |
Typography utility classes | Yes |
layout.min.css |
Layout and grid utility classes | Yes |
element.min.css |
Element styles (buttons, forms, etc.) | Yes |
animation.min.css |
Animation utility classes | Yes |
accessibility.min.css |
Screen reader and a11y utilities | Yes |
web-components.min.css |
Web component styles | Yes |
For quick prototyping or projects without a build system, load styles directly via CDN.
<!-- Full bundle -->
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/css/styles.min.css">
<!-- Or load specific files -->
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/css/tokens.min.css">
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/css/typography.min.css">
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/css/layout.min.css">
For optimal performance, load critical styles as render-blocking in the <head> to prevent Flash of Unstyled Text (FOUT) and Flash of Unstyled Content (FOUC):
<head>
<!-- Critical: Render-blocking CSS (prevents FOUT/FOUC) -->
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/css/font-faces.min.css" blocking="render">
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/css/tokens.min.css" blocking="render">
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/css/base.min.css" blocking="render">
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/css/typography.min.css" blocking="render">
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/css/web-components.min.css" blocking="render">
<!-- Non-critical: Load async using media="print" trick -->
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/css/layout.min.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/css/animation.min.css" media="print" onload="this.media='all'">
</head>
Why this matters:
blocking="render" ensures styles load before first paintmedia="print" trick to load asynchronously without blocking renderFor projects that need programmatic access to design tokens and style utilities without a build system:
<script src="https://unpkg.com/@universityofmaryland/web-styles-library/dist/cdn.js"></script>
<script>
const { token, layout, typography } = window.Styles;
console.log(token.color.red); // #E21833
</script>
For production environments, pin to a specific version to avoid unexpected changes:
<!-- Pin to specific version for production -->
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library@1.7.8/dist/css/styles.min.css">
<script src="https://unpkg.com/@universityofmaryland/web-styles-library@1.7.8/dist/cdn.js"></script>
The library includes pre-built Tailwind CSS integration files:
<!-- Tailwind 4 theme integration (use with Tailwind CSS) -->
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/tailwind.css">
<!-- Theme-only (no Tailwind dependency, just UMD design tokens as CSS variables) -->
<link rel="stylesheet" href="https://unpkg.com/@universityofmaryland/web-styles-library/dist/tailwind-theme.css">
/** @type {import('tailwindcss').Config} */
import * as Styles from '@universityofmaryland/web-styles-library';
import plugin from 'tailwindcss/plugin';
const { token, root: utilities, outputStyles: components } = Styles;
export default {
content: ['./src/**/*.{html,js,jsx,ts,tsx}'],
theme: {
extend: {
colors: token.color,
spacing: token.spacing,
fontFamily: token.font.family,
},
},
plugins: [
plugin(({ addUtilities, addComponents }) => {
addUtilities(utilities);
addComponents(components);
}),
],
};
For production applications, split CSS into critical (render-blocking) and non-critical (deferred) bundles to optimize Core Web Vitals and prevent FOUT/FOUC.
| Benefit | Description |
|---|---|
| Prevents FOUT | Typography loads before first paint |
| Prevents FOUC | Web components styled immediately |
| Better LCP | Faster Largest Contentful Paint |
| Better CLS | No layout shift from late-loading styles |
| Category | Files | Purpose |
|---|---|---|
| Critical | font-faces, tokens, base, typography, web-components | Must load before first paint |
| Non-Critical | accessibility, layout, element | Can load after first paint |
src/
├── styles/
│ ├── critical.css # Critical CSS imports
│ └── main.css # Non-critical CSS imports
├── index.html
└── vite.config.ts
/* Critical CSS - Render blocking */
@import '@universityofmaryland/web-styles-library/css/font-faces.min.css';
@import '@universityofmaryland/web-styles-library/css/tokens.min.css';
@import '@universityofmaryland/web-styles-library/css/base.min.css';
@import '@universityofmaryland/web-styles-library/css/typography.min.css';
@import '@universityofmaryland/web-styles-library/css/web-components.min.css';
/* Non-critical CSS - Deferred loading */
@import '@universityofmaryland/web-styles-library/css/accessibility.min.css';
@import '@universityofmaryland/web-styles-library/css/layout.min.css';
@import '@universityofmaryland/web-styles-library/css/element.min.css';
/* Your application styles */
import { defineConfig } from 'vite';
export default defineConfig({
build: {
rollupOptions: {
input: {
critical: 'src/styles/critical.css',
main: 'src/styles/main.css',
},
output: {
assetFileNames: (assetInfo) => {
if (assetInfo.name?.endsWith('.css')) {
return 'assets/[name].[hash].css';
}
return 'assets/[name].[hash][extname]';
},
},
},
cssCodeSplit: true,
},
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>UMD App</title>
<!-- Hide body until critical CSS loads -->
<style id="critical-inline">
body { content-visibility: hidden; }
</style>
<!-- Critical CSS - Render blocking -->
<link rel="stylesheet" href="/critical.css" blocking="render">
<!-- Non-critical CSS - Deferred -->
<link rel="stylesheet" href="/main.css" media="print" onload="this.media='all'">
<noscript>
<link rel="stylesheet" href="/main.css">
</noscript>
</head>
<body>
<!-- App content -->
</body>
</html>
Beyond CDN and direct bundler imports, the styles library supports several integration patterns for different environments and build systems.
Import CSS directly in your entry file - your bundler handles the rest.
// Works with Vite, Webpack, Rollup, etc.
import '@universityofmaryland/web-styles-library/css/tokens.min.css';
import '@universityofmaryland/web-styles-library/css/typography.min.css';
Pros: Zero config, tree-shaking, source maps, bundle optimization Cons: Requires a bundler
Copy CSS files during build to your public/static directory.
npm script approach:
{
"scripts": {
"copy:styles": "mkdir -p public/styles && cp node_modules/@universityofmaryland/web-styles-library/dist/css/*.min.css public/styles/"
}
}
Vite plugin approach:
import { copyFileSync, mkdirSync } from 'fs';
function copyStylesPlugin() {
return {
name: 'copy-styles',
writeBundle() {
const src = 'node_modules/@universityofmaryland/web-styles-library/dist/css';
const dest = 'dist/styles';
mkdirSync(dest, { recursive: true });
copyFileSync(`${src}/tokens.min.css`, `${dest}/tokens.min.css`);
copyFileSync(`${src}/typography.min.css`, `${dest}/typography.min.css`);
}
};
}
Pros: Works with any build system, full control over output location Cons: Manual path maintenance when package updates
Use @import in your CSS files with PostCSS processing.
/* main.css */
@import '@universityofmaryland/web-styles-library/dist/css/tokens.min.css';
@import '@universityofmaryland/web-styles-library/dist/css/typography.min.css';
/* Your custom styles */
.my-component {
color: var(--umd-color-red);
}
// postcss.config.js
module.exports = {
plugins: {
'postcss-import': {},
}
};
Pros: Integrates with existing CSS pipeline, allows composition Cons: Requires PostCSS setup
Generate CSS strings at runtime or build time using exported functions.
import { generateCSSStrings } from '@universityofmaryland/web-styles-library/exports/generate';
import { writeFileSync } from 'fs';
async function build() {
const css = await generateCSSStrings();
// Write to files
writeFileSync('public/tokens.css', css.tokens);
writeFileSync('public/typography.css', css.typography);
// Or inline in HTML
const html = `<style>${css.tokens}${css.typography}</style>`;
}
SSR middleware example:
let cssCache = null;
app.get('/styles/:category.css', async (req, res) => {
if (!cssCache) {
const { generateCSSStrings } = await import('@universityofmaryland/web-styles-library/exports/generate');
cssCache = await generateCSSStrings();
}
res.type('text/css').send(cssCache[req.params.category]);
});
Pros: Dynamic generation, works with SSR frameworks Cons: Runtime overhead, more complex setup
Use pre-built Tailwind theme files.
/* Import in your main CSS */
@import '@universityofmaryland/web-styles-library/dist/tailwind.css';
/* Or theme-only (no Tailwind dependency) */
@import '@universityofmaryland/web-styles-library/dist/tailwind-theme.css';
Pros: Works with Tailwind projects, includes CSS variables Cons: Larger file size than targeted imports
Copy files and reference via <link> tags.
# Copy during deployment
cp node_modules/@universityofmaryland/web-styles-library/dist/css/tokens.min.css public/
cp node_modules/@universityofmaryland/web-styles-library/dist/css/typography.min.css public/
<head>
<link rel="stylesheet" href="/tokens.min.css" blocking="render">
<link rel="stylesheet" href="/typography.min.css" blocking="render">
</head>
Pros: Works anywhere, no build tools needed Cons: Manual file management, extra HTTP requests
| Approach | Bundler Required | Best For |
|---|---|---|
| Direct Import | Yes | Modern web apps (Vite, Webpack) |
| Build Extraction | No | Static sites, SSR, CI/CD pipelines |
| PostCSS | Yes | CSS composition, custom pipelines |
| Programmatic | No | SSR, dynamic themes, Node.js apps |
| Tailwind | Yes | Tailwind CSS projects |
| Static Links | No | Legacy systems, HTML-only |
| File | Description |
|---|---|
dist/css/font-faces.min.css |
@font-face rules for all font families |
dist/css/tokens.min.css |
CSS custom properties for design tokens |
dist/css/typography.min.css |
Typography utility classes |
dist/css/styles.min.css |
Full bundle (all CSS combined) |
dist/tailwind.css |
Tailwind 4 theme integration |
dist/tailwind-theme.css |
Theme-only CSS variables |
exports/generate |
Programmatic CSS generation functions |
import * as Styles from '@universityofmaryland/web-styles-library';
// Pre-render CSS (fonts, variables, resets)
Styles.preRenderCss.then((css) => {
const style = document.createElement('style');
style.textContent = `${Styles.typography.fontFace.base64fonts} ${css}`;
document.head.appendChild(style);
});
// Post-render CSS (utilities and components)
Styles.postRenderCss.then((css) => {
const style = document.createElement('style');
style.textContent = css;
document.head.appendChild(style);
});
Note: Design tokens have been extracted to a standalone package
@universityofmaryland/web-token-library. The styles package re-exports these tokens for backwards compatibility. For new projects, consider importing directly from the tokens package for better tree-shaking.
Official UMD brand values accessible as JavaScript objects:
// Recommended (direct from tokens package)
import * as token from '@universityofmaryland/web-token-library';
// Also supported (backwards compatibility)
import { token } from '@universityofmaryland/web-styles-library';
// Colors
token.color.red; // #e21833
token.color.gold; // #FFD200
token.color.black; // #000000
// Spacing
token.spacing.sm; // 0.5rem
token.spacing.md; // 1rem
token.spacing.lg; // 1.5rem
// Typography
token.font.family.sans; // 'Helvetica Neue', Helvetica, Arial, sans-serif
token.font.size.base; // 1rem
token.font.weight.bold; // 700
// Breakpoints
token.media.breakpoints.tablet; // 768px
token.media.breakpoints.desktop; // 1024px
Pre-built utility classes for common patterns:
/* Layout spacing */
.umd-layout-space-vertical-landing
.umd-layout-space-horizontal-larger
/* Grid systems */
.umd-grid-gap-three
.umd-grid-gap-masonry
/* Typography */
.umd-sans-largest-uppercase
.umd-text-rich-simple-large
/* Backgrounds */
.umd-background-quarter-light
.umd-background-full-dark;
All styles are available as JavaScript objects:
import {
animation,
element,
layout,
} from '@universityofmaryland/web-styles-library';
// Animation utilities
const fadeIn = animation.line.fadeInSimpleDark;
// Returns: { className: 'umd-fadein-simple-dark', ...styles }
// Element styles
const primaryButton = element.action.primary.normal;
// Layout patterns
const gridThree = layout.grid.columnsThree;
The Styles Library provides all visual styling for web components:
<!-- Components use styles automatically -->
<umd-element-card data-theme="dark">
<!-- Styled by the styles package -->
</umd-element-card>
<!-- Combine with utility classes -->
<div class="umd-layout-space-vertical-landing">
<umd-element-hero><!-- content --></umd-element-hero>
</div>
Elements rely on styles for all visual properties:
import { Composite } from '@universityofmaryland/web-elements-library';
// Elements automatically include necessary styles
Feed components inherit consistent styling:
import { news } from '@universityofmaryland/web-feeds-library';
// Feeds use grid and card styles automatically
import * as Styles from '@universityofmaryland/web-styles-library';
// Option 1: Use pre-built bundles
async function loadStyles() {
const preRender = await Styles.preRenderCss;
const postRender = await Styles.postRenderCss;
// Apply styles to document
const fonts = Styles.typography.fontFace.base64fonts;
document.head.insertAdjacentHTML(
'beforeend',
`<style>${fonts} ${preRender}</style>`,
);
// After body renders
document.head.insertAdjacentHTML('beforeend', `<style>${postRender}</style>`);
}
// Option 2: Select specific styles
const selectedStyles = await Styles.utilities.create.style.toString({
...Styles.layout.grid,
...Styles.element.action,
...Styles.typography.sans,
});
// In JavaScript
const theme = {
primaryColor: Styles.token.color.red,
secondaryColor: Styles.token.color.gold,
baseSpacing: Styles.token.spacing.md,
};
// As CSS variables
Styles.utilities.dom.tokens(Styles.variables);
// Creates: --color-red: #e21833; etc.
// Media query tokens
const { breakpoints } = Styles.token.media;
// Use in CSS-in-JS
const responsiveCard = {
padding: Styles.token.spacing.md,
[`@media (min-width: ${breakpoints.tablet})`]: {
padding: Styles.token.spacing.lg,
},
[`@media (min-width: ${breakpoints.desktop})`]: {
padding: Styles.token.spacing.xl,
},
};
See our Tailwind Integration Guide for detailed setup instructions.
Full TypeScript support with type definitions:
import type {
JssObject,
JssEntry,
} from '@universityofmaryland/web-styles-library';
// Type-safe style objects
const customStyle: JssObject = {
className: 'my-custom-class',
color: Styles.token.color.red,
padding: Styles.token.spacing.md,
};
All styles follow WCAG 2.1 AA guidelines:
# Run tests
npm test
# Watch mode
npm run test:watch
# Coverage report
npm run test:coverage
See the main repository for contribution guidelines.
University of Maryland