Main Content Area
Lorem ipsum dolor sit amet...
Craft beautiful interfaces with less markup — Axiom01 enhances your HTML, not your class count.🔥
Read the Docs Get AxiomAxiom01 is a thoughtfully designed UI framework that prioritizes simplicity and flexibility. Currently in early development (v0.1.0), it takes a different approach to web interfaces.
Unlike frameworks that require countless utility classes, Axiom01 styles semantic HTML elements directly, resulting in cleaner markup that's easier to read and maintain.
Instead of littering your HTML with utility classes, Axiom01 uses strategic class composition that respects the semantic meaning of your elements while providing all the styling power you need.
With 20+ built-in themes ranging from professional light/dark modes to vibrant aesthetic options, switching the entire look of your application requires changing just one attribute.
Designed for performance with a focus on only including what you'll actually use, Axiom01 aims to keep your applications responsive and fast-loading.
Built to work with the grain of HTML and CSS, not against it, enhancing the natural capabilities of the web platform rather than fighting them.
Being developed with keyboard navigation and screen reader compatibility as core principles, not afterthoughts.
Start building with Axiom01 in minutes.
git clone https://github.com/Sol-Roth-Media/axiom01
Or install via NPM:
npm install axiom01
<link rel="stylesheet" href="css/axiom.css">
<script src="js/scripts.js"></script>
Axiom01 comes with a powerful theming system built-in.
<html data-theme="dark">
The core philosophy behind Axiom is to keep your HTML clean, semantic, and focused on content, while your CSS handles the layout and styling. This approach offers several benefits:
<main>
, <section>
, <article>
, and
<aside>
elements.
Using Axiom is simple. Just follow these steps:
axiom.css
file in the <head>
of your HTML.<main>
,
<section>
, <article>
, and <aside>
.
For more detailed instructions and examples, refer to the Axiom documentation below.
Axiom's grid system is designed to be intuitive and classless for basic layouts. It automatically creates
layouts based on the nesting of semantic elements. Use the .row
class for explicit multi-column
control.
Direct children of <main>
like <section>
or <article>
will typically stack vertically by default.
Content in a single column section within main.
<main>
<section>
<p>Content in a single column section within main.</p>
</section>
</main>
Use an <article>
and an <aside>
as direct children of a <section>
to potentially create a main content/sidebar layout (behaviour might depend on specific CSS grid rules).
Lorem ipsum dolor sit amet...
<main>
<section> <!-- Wrapper for article+aside -->
<article>
<h5>Main Content Area</h5>
<p>Lorem ipsum dolor sit amet...</p>
</article>
<aside>
<h5>Sidebar</h5>
<p>Sidebar content...</p>
</aside>
</section>
</main>
Use a <div class="row">
wrapper around direct child elements (like
<article>
) to create an explicit 12-column grid row. Children will automatically take up
space. Use .col-*
classes for specific spans.
Content in column 1 (col-6)
Content in column 2 (col-6)
<div class="row">
<article class="col-6">
<p>Content in column 1 (col-6)</p>
</article>
<article class="col-6">
<p>Content in column 2 (col-6)</p>
</article>
</div>
Content in column 1 (col-4)
Content in column 2 (col-4)
Content in column 3 (col-4)
<div class="row">
<article class="col-4">
<p>Content in column 1 (col-4)</p>
</article>
<article class="col-4">
<p>Content in column 2 (col-4)</p>
</article>
<article class="col-4">
<p>Content in column 3 (col-4)</p>
</article>
</div>
Content in column 1 (col-3)
Content in column 2 (col-3)
Content in column 3 (col-3)
Content in column 4 (col-3)
<div class="row">
<article class="col-3">
<p>Content in column 1 (col-3)</p>
</article>
<article class="col-3">
<p>Content in column 2 (col-3)</p>
</article>
<article class="col-3">
<p>Content in column 3 (col-3)</p>
</article>
<article class="col-3">
<p>Content in column 4 (col-3)</p>
</article>
</div>
Axiom provides a typographic scale and default styles for common text elements.
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>
<h5>Heading 5</h5>
<h6>Heading 6</h6>
This is a paragraph of text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor.
<p>This is a paragraph of text...</p>
This is a blockquote. It represents content quoted from another source.
<blockquote>
<p>This is a blockquote...</p>
<footer>- <cite>Source Author or Title</cite></footer>
</blockquote>
<figure>
<img src="placeholder.jpg" alt="Description of image">
<figcaption>This is a figcaption...</figcaption>
</figure>
Use the <code>
element for inline snippets, like font-family:
var(--a-font-family-sans);
.
Use <pre><code class="language-css">...</code></pre>
for code blocks:
/* Example CSS code block */
body {
font-family: var(--a-font-family-sans);
color: var(--a-color-on-surface);
background-color: var(--a-color-surface);
}
<p>Inline <code>code</code> example.</p>
<pre><code class="language-css">
/* Code block example */
.some-class {
color: red;
}
</code></pre>
You can use utility classes like .standout
if defined in your site-specific CSS.
This paragraph uses the "standout" class for emphasis.
<p class="standout">This paragraph uses the "standout" class...</p>
<dl>
<dt>Term 1</dt>
<dd>Definition for the first term.</dd>
<dt>Term 2</dt>
<dd>Description or definition for the second term.</dd>
</dl>
This paragraph demonstrates text flowing into multiple columns using the .text-columns
utility
class (if defined). Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
<div class="text-columns">
<p>This paragraph demonstrates text flowing into multiple columns...</p>
</div>
/* Ensure this or similar exists in site.css or axiom.css */
.text-columns {
column-count: 2; /* Or more */
column-gap: var(--a-space-large); /* Adjust gap */
}
Reusable interface elements built with Axiom styles and semantic HTML.
Indicates ongoing processes. Requires CSS for animation.
<!-- Basic Throbber -->
<div class="throbber" role="status" aria-label="Loading">
<div class="throbber-circle"></div>
</div>
<!-- Multi-Ring Throbber -->
<div class="throbber" role="status" aria-label="Loading">
<div class="throbber-circle"></div>
<div class="throbber-circle inner"></div>
</div>
<!-- JS Controlled (HTML part) -->
<div class="throbber-container">
<button id="toggle-loading" type="button">Start Loading</button>
<div id="loading-throbber" class="throbber" role="status" aria-hidden="true">
<div class="throbber-circle"></div>
</div>
</div>
// Basic JS for the toggle example (Ensure this is in scripts.js)
document.addEventListener('DOMContentLoaded', () => {
const toggleButton = document.getElementById('toggle-loading');
const throbber = document.getElementById('loading-throbber');
if (toggleButton && throbber) { // Check if elements exist
toggleButton.addEventListener('click', () => {
const isLoading = throbber.classList.toggle('active');
throbber.setAttribute('aria-hidden', !isLoading);
toggleButton.textContent = isLoading ? 'Stop Loading' : 'Start Loading';
});
}
});
Display contextual feedback messages using `alert` and modifier classes.
<div class="alert alert-success" role="alert">
Success! Your operation was completed.
</div>
<div class="alert alert-error" role="alert">
Error! Something went wrong.
</div>
<div class="alert alert-info" role="alert">
Info: This is an informational message.
</div>
Show the user's location within the site hierarchy using nested lists.
<nav class="breadcrumbs" aria-label="Breadcrumb">
<ol>
<li><a href="#">Home</a></li>
<li><a href="#">Category</a></li>
<li aria-current="page">Current Page</li>
</ol>
</nav>
Provide brief information on hover using the `tooltip` class and `data-tooltip` attribute.
Focusable Span
<button type="button" class="tooltip" data-tooltip="Tooltip for the button!">Hover Button</button>
<span class="tooltip" data-tooltip="Tooltip for the span." tabindex="0">Focusable Span</span>
Show temporary, non-intrusive messages. Usually triggered by JavaScript.
(Toasts are typically shown dynamically with JavaScript)
<!-- Example Toast Structure (often added/removed by JS) -->
<div class="toast toast-success" role="alert" aria-live="assertive">
Success! Your changes have been saved.
</div>
<div class="toast toast-error" role="alert" aria-live="assertive">
Error! Could not perform the action.
</div>
Collapsible content panels. Requires JavaScript for interaction.
Content for the first accordion item. This is initially hidden.
Content for the second item. More details can go here.
<section class="accordion">
<!-- Accordion Item 1 -->
<div>
<h4 id="acc1-header"> <!-- Heading level can vary -->
<button type="button" aria-expanded="false" aria-controls="acc1-content">
Accordion Title 1
</button>
</h4>
<div id="acc1-content" role="region" aria-labelledby="acc1-header" hidden>
<p>Panel content 1...</p>
</div>
</div>
<!-- Accordion Item 2 -->
<div>
<h4 id="acc2-header">
<button type="button" aria-expanded="false" aria-controls="acc2-content">
Accordion Title 2
</button>
</h4>
<div id="acc2-content" role="region" aria-labelledby="acc2-header" hidden>
<p>Panel content 2...</p>
</div>
</div>
</section>
// Basic JS for Accordion (Ensure this is in scripts.js and handles multiple accordions)
document.addEventListener('DOMContentLoaded', () => {
const accordionButtons = document.querySelectorAll('.accordion h4 button[aria-controls]');
accordionButtons.forEach(button => {
button.addEventListener('click', () => {
const panel = document.getElementById(button.getAttribute('aria-controls'));
const isExpanded = button.getAttribute('aria-expanded') === 'true';
button.setAttribute('aria-expanded', !isExpanded);
panel.toggleAttribute('hidden');
});
// Add keyboard support (Enter/Space) if not already present
});
});
Switch between different content panels. Requires JavaScript for interaction.
This is the content for the 'Info' tab.
This section shows the 'Details'.
Here are the 'Settings'.
<section class="tabs">
<ul role="tablist" aria-label="Descriptive Label">
<li role="tab" id="tab1" aria-selected="true" aria-controls="panel1" tabindex="0">Tab 1</li>
<li role="tab" id="tab2" aria-selected="false" aria-controls="panel2" tabindex="-1">Tab 2</li>
</ul>
<div id="panel1" role="tabpanel" aria-labelledby="tab1" tabindex="0">
<p>Content for Tab 1.</p>
</div>
<div id="panel2" role="tabpanel" aria-labelledby="tab2" hidden tabindex="0">
<p>Content for Tab 2.</p>
</div>
</section>
// Basic JS for Tabs (Ensure this is in scripts.js and handles multiple tab groups)
document.addEventListener('DOMContentLoaded', () => {
const tabLists = document.querySelectorAll('.tabs [role="tablist"]');
tabLists.forEach(tabList => {
const tabs = tabList.querySelectorAll('[role="tab"]');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
// Deactivate all tabs in the group
tabs.forEach(t => {
t.setAttribute('aria-selected', 'false');
t.setAttribute('tabindex', '-1');
const panel = document.getElementById(t.getAttribute('aria-controls'));
if (panel) panel.hidden = true;
});
// Activate the clicked tab
tab.setAttribute('aria-selected', 'true');
tab.setAttribute('tabindex', '0');
const activePanel = document.getElementById(tab.getAttribute('aria-controls'));
if (activePanel) activePanel.hidden = false;
});
// Add keyboard navigation (Arrows) if not already present
});
});
});
This is a card component with minimal classes.
Reveal a list of options on interaction. Requires JavaScript.
<div class="dropdown">
<button type="button" class="dropdown-toggle" aria-haspopup="true" aria-expanded="false" aria-controls="dd-menu-id">
Menu
</button>
<ul class="dropdown-menu" id="dd-menu-id" role="menu" aria-hidden="true">
<li role="none"><a href="#" role="menuitem">Option 1</a></li>
<li role="none"><a href="#" role="menuitem">Option 2</a></li>
<li role="separator"></li> <!-- Optional -->
<li role="none"><a href="#" role="menuitem">Option 3</a></li>
</ul>
</div>
// Basic JS for Dropdown (Ensure this is in scripts.js)
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.dropdown-toggle').forEach(toggle => {
toggle.addEventListener('click', () => {
const menu = toggle.nextElementSibling; // Assumes menu is the next sibling
const isOpen = menu.classList.toggle('show');
menu.setAttribute('aria-hidden', !isOpen);
toggle.setAttribute('aria-expanded', isOpen);
});
});
// Add click outside to close functionality if needed
});
Indicate the completion status of a task. Can be updated with JavaScript.
<label for="prog-bar">Task Progress:</label>
<div class="progress-bar" id="prog-bar" role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100">
<div class="progress" style="width: 50%;"></div>
</div>
// Basic JS for Progress Bar button (Ensure this is in scripts.js)
document.addEventListener('DOMContentLoaded', () => {
const progressButton = document.querySelector('#progress-bar-demo .progress-btn');
const progressBar = document.querySelector('#progress-bar-demo .progress-bar');
const progressInner = progressBar ? progressBar.querySelector('.progress') : null;
let progressValue = 0; // Start at 0 or current value
if (progressButton && progressBar && progressInner) {
// Get initial value if set
const initialValue = parseInt(progressBar.getAttribute('aria-valuenow'), 10);
if (!isNaN(initialValue)) {
progressValue = initialValue;
}
progressButton.addEventListener('click', () => {
progressValue = Math.min(progressValue + 10, 100); // Increment by 10%, max 100%
if (progressInner) {
progressInner.style.width = `${progressValue}%`;
}
progressBar.setAttribute('aria-valuenow', progressValue);
// Optional: Disable button when progress is complete
if (progressValue === 100) {
progressButton.textContent = 'Completed!';
progressButton.disabled = true;
}
});
}
});
The navbar provides consistent page navigation. It includes a logo, main navigation links, a mobile hamburger menu toggle, and a theme switcher. It's designed to be sticky at the top.
The following HTML is used for the main navigation bar at the top of this page:
<header class="full-bleed">
<nav class="navbar">
<!-- Logo with Version -->
<a href="#" class="logo" aria-label="Axiom Framework Home v0.1">
<div class="logo-text">
<span>[</span>
<span>A</span>
<span>X</span>
<span>1</span>
<span>0</span>
<span>M</span>
<span>]</span>
</div>
<small class="version">v0.1</small>
</a>
<!-- Hamburger Menu Button (for mobile) -->
<button class="menu-toggle" aria-label="Toggle Navigation" aria-expanded="false" aria-controls="nav-links-main">
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</button>
<!-- Main Navigation Links -->
<ul class="nav-links" id="nav-links-main">
<li><a href="#about">About</a></li>
<li><a href="#usage">Get started</a></li>
<!-- ... other list items ... -->
<li><a href="https://github.com/Sol-Roth-Media/axiom01" target="_blank" rel="noopener noreferrer">GitHub</a></li>
</ul>
<!-- Standalone Theme Toggle Button -->
<button class="theme-toggle" title="Toggle Dark/Light Mode" aria-label="Toggle Dark Light Mode">
☀ <!-- Default to sun icon, JS updates it -->
</button>
</nav>
</header>
.navbar
: Main container for the navigation bar. Styled with flexbox..logo
, .logo-text
, .version
: For styling the logo and version
number.
.menu-toggle
, .bar
: For the mobile hamburger menu. Its visibility and open/close
state are controlled by CSS media queries and JavaScript (in js/scripts.js
).
.nav-links
: The `ul` containing the navigation items. JavaScript toggles an
.open
class for mobile display.
.theme-toggle
: The button for switching themes. JavaScript handles the theme change and icon
update.
.full-bleed
on <header>
: Allows the navbar background to span the full
viewport width.
Refer to axiom.css
for detailed styling and js/scripts.js
for interactive
behaviors.
Axiom provides predefined color variables for consistency.
Examples of generated color variables:
Neutral shades for backgrounds, text, and UI elements.
Examples of form layouts and elements.
Axiom01 now includes a build system to help you prepare your project for production.
The build script helps validate, concatenate, and minify your CSS and JavaScript files.
# Make the script executable
chmod +x build.sh
# Run the build script
./build.sh
# Or use NPM if you prefer
npm run build
The build script will create a dist
directory with optimized files ready for production:
<!-- In production, use the optimized files -->
<link rel="stylesheet" href="dist/css/axiom.min.css">
<script src="dist/js/axiom.min.js"></script>
Axiom01 now includes a central configuration file (axiom_config.css
) that defines framework-wide
settings:
Use the new breakpoint variables in your media queries for consistency:
/* Mobile first approach */
.element {
/* Base styles for mobile */
}
@media (min-width: var(--a-breakpoint-md)) {
.element {
/* Styles for tablets and up */
}
}
@media (min-width: var(--a-breakpoint-lg)) {
.element {
/* Styles for desktops and up */
}
}
Axiom01 can now be installed via NPM:
npm install axiom01
This allows you to integrate Axiom01 into your existing build processes or frameworks.