Neubrutalism CSS
A minimalist, high-contrast CSS library inspired by Brutalist design principles. Bold, clean, and unapologetically simple.
Getting Started
Neubrutalism CSS is a lightweight, dependency-free CSS library that provides bold, high-contrast components perfect for modern web applications.
Key Features
- 🎨 High-contrast black and white design
- ⚡ Lightweight (~70KB unminified)
- 🌙 Built-in dark mode support
- ♿ Accessibility-first approach
- 📱 Responsive components
- 🔧 Customizable with CSS custom properties
- 🎯 No JavaScript dependencies for styling
Installation
CDN (Recommended)
Add the following to your HTML <head>:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/OshekharO/Neubrutalism@main/neubrutalism.css">Optional JavaScript
For interactive components like toasts and dark mode toggle:
<script src="https://cdn.jsdelivr.net/gh/OshekharO/Neubrutalism@main/neubrutalism.js"></script>Download
Download the files from GitHub and include them in your project.
CSS Custom Properties
Customize Neubrutalism by overriding CSS custom properties:
Core Colors
:root {
--nb-primary: #000; /* Primary color (black) */
--nb-secondary: #fff; /* Secondary color (white) */
--nb-accent: #3498db; /* Accent color for focus states */
--nb-success: #2ecc71;
--nb-danger: #e74c3c;
--nb-warning: #f39c12;
--nb-info: #3498db;
}Shadow & Border
:root {
--nb-border-width: 2px;
--nb-border-radius: 4px;
--nb-shadow-offset: 4px;
--nb-shadow-color: var(--nb-primary);
}Typography
Headings h1–h6 are styled automatically. Additional classes:
<p class="nb-lead">Lead paragraph text</p>
<p class="nb-small">Small text</p>
<p class="nb-muted">Muted text</p>
<span class="nb-mark">Highlighted text</span>
<!-- Display headings -->
<p class="nb-display-1">Display 1</p>
<p class="nb-display-2">Display 2</p>
<!-- Blockquote -->
<blockquote class="nb-blockquote">
Quote text
<span class="nb-blockquote-author">- Author</span>
</blockquote>
<!-- Code block -->
<pre class="nb-code-block"><code>your code here</code></pre>Layout & Grid
<!-- Responsive grid -->
<div class="nb-grid nb-grid-3">
<div>Column 1</div>
<div>Column 2</div>
<div>Column 3</div>
</div>
<!-- Available: nb-grid-1 through nb-grid-6 -->
<!-- Bordered grid -->
<div class="nb-grid-bordered nb-grid-3">...</div>Containers
<div class="nb-container">Max 1200px centered</div>
<div class="nb-container-sm">Max 540px</div>
<div class="nb-container-md">Max 720px</div>
<div class="nb-container-lg">Max 960px</div>
<div class="nb-container-card">Card-style</div>
<div class="nb-container-bordered">With border & shadow</div>
<!-- Color variants -->
<div class="nb-container-primary">Primary</div>
<div class="nb-container-success">Success</div>
<div class="nb-container-warning">Warning</div>
<div class="nb-container-danger">Danger</div>Badges & Tags
<!-- Badges -->
<span class="nb-badge">Default</span>
<span class="nb-badge nb-badge-primary">Primary</span>
<span class="nb-badge nb-badge-success">Success</span>
<span class="nb-badge nb-badge-danger">Danger</span>
<span class="nb-badge nb-badge-warning">Warning</span>
<span class="nb-badge nb-badge-pill">Pill</span>
<!-- Tags -->
<span class="nb-tag">Default</span>
<span class="nb-tag nb-tag-primary">Primary</span>
<span class="nb-tag">Removable <span class="nb-tag-close">×</span></span>Cards
<div class="nb-card">
<div class="nb-card-header">Header</div>
<div class="nb-card-body">
<h3>Card Title</h3>
<p>Card content goes here.</p>
</div>
<div class="nb-card-footer">
<button class="nb-btn nb-btn-small">Action</button>
</div>
</div>Alerts
<div class="nb-alert nb-alert-success">Success alert</div>
<div class="nb-alert nb-alert-danger">Danger alert</div>
<div class="nb-alert nb-alert-warning">Warning alert</div>
<div class="nb-alert nb-alert-info">Info alert</div>Modals
<input class="nb-modal-state" id="my-modal" type="checkbox" />
<div class="nb-modal">
<label class="nb-modal-overlay" for="my-modal"></label>
<div class="nb-modal-container">
<label class="nb-modal-close" for="my-modal">...</label>
<div class="nb-modal-content">
<h2 class="nb-modal-title">Title</h2>
<div class="nb-modal-body">Content</div>
<div class="nb-modal-footer">
<label class="nb-btn" for="my-modal">Close</label>
</div>
</div>
</div>
</div>
<label class="nb-btn" for="my-modal">Open Modal</label>Accordion
<div class="nb-accordion">
<div class="nb-accordion-item">
<input type="checkbox" id="acc-1" class="nb-accordion-state" />
<label for="acc-1" class="nb-accordion-header">
Question <span class="nb-accordion-icon">+</span>
</label>
<div class="nb-accordion-content">
<p>Answer goes here.</p>
</div>
</div>
</div>Tabs
<div class="nb-tabs">
<input class="nb-tab-input" name="tabs" type="radio" id="tab-1" checked />
<label class="nb-tab-label" for="tab-1">Tab 1</label>
<div class="nb-tab-panel"><p>Tab 1 content</p></div>
<input class="nb-tab-input" name="tabs" type="radio" id="tab-2" />
<label class="nb-tab-label" for="tab-2">Tab 2</label>
<div class="nb-tab-panel"><p>Tab 2 content</p></div>
</div>
<!-- Scrollable tabs: same pattern, use class="nb-tabs-scrollable" -->Dropdown
<div class="nb-dropdown nb-dropdown-primary">
<button class="nb-dropdown-toggle">Select Option</button>
<div class="nb-dropdown-menu">
<a href="#" class="nb-dropdown-menu-item">Option 1</a>
<a href="#" class="nb-dropdown-menu-item">Option 2</a>
</div>
</div>Tables
<table class="nb-table">
<thead>
<tr><th>Name</th><th>Status</th></tr>
</thead>
<tbody>
<tr><td>Alice</td><td>Active</td></tr>
</tbody>
</table>
<!-- Modifiers: nb-table-compact, nb-table-borderless -->
<!-- Row highlights: nb-row-success, nb-row-warning, nb-row-danger, nb-row-info -->
<!-- Scrollable: wrap in <div class="nb-table-scrollable"> -->Forms
<div class="nb-pre-form">
<form class="nb-form">
<div class="nb-form-group">
<input type="text" placeholder="Name" class="nb-form-input" />
</div>
<div class="nb-form-group">
<input type="email" placeholder="Email" class="nb-form-input" />
</div>
<button type="submit" class="nb-form-btn">Submit</button>
</form>
</div>
<!-- Checkbox -->
<label class="nb-checkbox">
Label <input type="checkbox" />
<span class="nb-checkbox-mark"></span>
</label>
<!-- Switch -->
<label class="nb-switch">
<input type="checkbox" />
<span class="nb-switch-slider"></span>
</label>
<!-- Range -->
<input type="range" class="nb-range" min="0" max="100" value="50" />Colors
<!-- Background -->
<div class="nb-bg-primary">Primary</div>
<div class="nb-bg-success">Success</div>
<div class="nb-bg-danger">Danger</div>
<div class="nb-bg-warning">Warning</div>
<div class="nb-bg-info">Info</div>
<!-- Text -->
<p class="nb-text-primary">Primary</p>
<p class="nb-text-success">Success</p>
<p class="nb-text-danger">Danger</p>
<p class="nb-text-muted">Muted</p>Dark Mode
Neubrutalism supports both system-preference dark mode (via prefers-color-scheme) and a manual class toggle.
<!-- Toggle via JS -->
<button onclick="toggleDarkMode(!isDarkMode())">Toggle Dark Mode</button>
<!-- Or add the class manually -->
<html class="nb-dark">Accessibility
- All interactive components support
:focus-visibleoutlines - Respects
prefers-reduced-motion - Use
.nb-skip-linkfor skip-navigation links - Use
.nb-sr-onlyfor screen-reader-only text aria-*attributes are used throughout JS utilities