Civility is a set of CSS and JS tools meant for building webapps in a very structured way. We provide:
If you build a website with semantic html, good accessibility, and aria attribute usage, a clean an unoffensive UI will be free via classless CSS.
By assuming that you are using good html structure and accessibility, our baselayer can provide more specific styles than standard classless CSS frameworks.
We provide a system for defining themes and colors. The majority of styles can be handled via updating these CSS variables. These classes are used to style the baselayer, but are also used to provide utility.css, which is a set of css utilities based on tachyons-css.
For some concepts that don't exist in HTML, we provide custom elements under the ui- namespace, such as ui-tag, ui-card, and ui-grid.
The Civility CLI provides build tools and development server for PWA applications. It supports configurable paths through both command-line options and a civility.json configuration file.
The CLI looks for a civility.json file in your project root. If not found, it uses sensible defaults:
{
"root": "./src",
"outdir": "./src/dist",
"icon": {
"source": "./src/static/icon.png",
"output": "./src/dist/icons"
}
}Configuration Options:
root: Root directory containing your app source (serves as base forindex.tsandworker.ts)outdir: Build output directoryicon.source: Source PNG file for icon generationicon.output: Output directory for generated icons
Build Application:
civility build # Build once
civility build --watch # Build with watch mode
civility build --outdir ./dist # Override output directoryDevelopment Server:
civility start # Start dev server on port 8000
civility start --port 3000 # Custom port
civility start --root ./app # Override root directory
civility start --prod # Production mode (caching enabled)Generate Icons:
civility icons # Use config defaults
civility icons --source icon.png # Override source
civility icons --output ./dist/icons # Override outputInitialize Configuration:
civility init # Create default civility.jsonThe CLI automatically generates entry points (index.ts and worker.ts) from your configured root directory, eliminating the need to specify individual entry points.
Include the framework and theme in your HTML:
<link rel="stylesheet" href="dist/civility.css">
<link rel="stylesheet" href="dist/themes/default.css">Civiity follows a layered approach where each layer builds upon the previous one:
- normalize.css - Browser consistency
- themes/[theme-name].css - Design tokens and variables
- base.css - Classless semantic styling
- components.css - Custom components with
ui-prefix - app.css - Your application-specific styles
Uses modern-normalize to smooth over browser quirks and provide consistent defaults.
Defines all design tokens used throughout the framework:
- Typography: Font families, sizes, weights, line heights
- Spacing: Consistent spacing scale using CSS custom properties
- Border radius: From small (4px) to full rounded
- Shadows: Elevation system for depth
- Transitions: Consistent animation timing
- Layout: Breakpoints and container sizes
- Z-index: Layering system for overlays
/* Typography */
--font-family-base, --font-family-mono
--f7 through --f1
--fw-normal, --fw-medium, --fw-semibold, --fw-bold
--lh-tight, --lh-base, --lh-relaxed
/* Spacing */
--s1 through --s7
/* Border radius */
--br-none, --br-sm, --br-base, --br-lg, --br-xl, --br-full
/* Shadows */
--shadow-sm through --shadow-xl
/* Transitions */
--transition-fast, --transition-base, --transition-slowA classless CSS layer that provides complete styling using only semantic HTML. The goal is that normalize.css + themes + base.css = a fully functional (if boring) application.
Civiity assumes proper semantic HTML structure:
<html>
<body>
<header>
<nav><!-- Navigation with ul > li structure --></nav>
</header>
<main><!-- Main content --></main>
<footer><!-- Footer content --></footer>
</body>
</html>- Landmark styling: Automatic layout for header, main, footer
- Navigation: Dropdown support for nested ul elements
- Typography: Complete heading and text styling
- Forms: Styled inputs, buttons, fieldsets with focus states
- Tables: Clean table styling with proper headers
- ARIA support: Automatic styling for
role="tab",role="tabpanel", etc. - Accessibility: Focus-visible support, reduced motion preferences
- Responsive: Mobile-first responsive design
Civiity automatically styles ARIA patterns:
<!-- Tab interface -->
<div role="tablist">
<button role="tab" aria-selected="true">Tab 1</button>
<button role="tab" aria-selected="false">Tab 2</button>
</div>
<div role="tabpanel">Content 1</div>
<div role="tabpanel" hidden>Content 2</div>Custom components using HTML custom elements with ui- prefix. These components are theme-aware but base.css has no knowledge of them.
<!-- Cards -->
<ui-card clickable>Card content</ui-card>
<!-- Badges -->
<ui-badge variant="success">Success</ui-badge>
<ui-badge variant="warning">Warning</ui-badge>
<ui-badge variant="error">Error</ui-badge>
<ui-badge variant="info">Info</ui-badge>
<!-- Layout -->
<ui-grid cols="3">Grid items</ui-grid>
<ui-stack direction="row" spacing="lg">Stacked items</ui-stack>
<!-- Progress -->
<ui-progress style="--progress-value: 75%"></ui-progress>
<!-- Alerts -->
<ui-alert variant="success">Success message</ui-alert>
<!-- Loading -->
<ui-spinner size="lg"></ui-spinner>
<!-- Button groups -->
<ui-button-group attached>
<button>Button 1</button>
<button>Button 2</button>
</ui-button-group>- Semantic: Uses custom elements, not classes
- Accessible: Built with ARIA patterns in mind
- Themeable: Respects theme variables
- Responsive: Adapts to different screen sizes
- Lightweight: No JavaScript required (except for interactive components)
Application-specific styles. Civiity handles common patterns, so app.css should only contain:
- Brand-specific styling (colors, custom layouts)
- Domain-specific components (e.g., flashcard styles for a learning app)
- Layout overrides for specific use cases
- Integration styles between framework and app logic
- Use theme variables instead of hardcoded values
- Prefer semantic HTML + framework over custom classes
- Only add custom styles for truly app-specific needs
- Keep it minimal - let the framework do the heavy lifting
Civility follows a strict neutral-first approach:
- Everything neutral by default: Uses
currentColor,--body,--background - Links are colored: Only
<a>elements use--primaryby default - Variants add color:
ui-badge variant="success"gets green styling - No hardcoded colors: All colors use theme variables
- Theme declares palette: Base, primary, secondary colors
- Mathematical color variations: Automatically generate lighter/darker variants
- Opt-in color classes: Add
primary,secondary,primary-inverseclasses as needed - Maintains neutral default: Color is always opt-in, never forced
Added complete HSL-based color definitions:
Base Colors:
- Black, Gray, White (neutrals)
- Blue, Green, Yellow, Orange, Red, Purple (brand colors)
Semantic Colors:
--error(red-based)--warning(orange-based)--info(blue-based)--success(green-based)
Application Colors:
--background/--background-dull--body/--body-dull--primary/--primary-dull--secondary/--secondary-dull
The existing colors.css file defines the final color variables using HSL composition:
--primary: hsl(var(--primaryH), var(--primaryS), var(--primaryL));
--primary-dull: hsl(var(--primaryH), var(--primaryS), var(--primaryL), 0.3);This enables mathematical color variations and maintains consistency.
<!-- Neutral by default -->
<ui-card>Content uses currentColor</ui-card>
<!-- Color when requested -->
<ui-badge variant="success">Green badge</ui-badge>
<ui-alert variant="error">Red alert</ui-alert>
<!-- Links are the only colored element -->
<a href="#link">Uses --primary color</a>