Overview
Haupia is a lightweight (just 28K minified!) component library for webpages, designed to be simple to use, to install, and to modify. It is made from just pure CSS, meaning no build steps, no JavaScript dependencies, no CSS processing to configure, no image directory to set up. While maybe not as feature-rich as some component libraries, Haupia is ideal when you want a minimum of fuss. Just drop the stylesheet onto your page, and you're off!
Usage
To install Haupia, just copy the stylesheet into your site, and link to it from your page. That's it! Go (coco)nuts!
Haupia only styles the CSS classes that are part of its API; it won't affect anything else on your page, so it is easily used alongside your existing CSS, or even alongside another front-end framework.
This simpler components just use the relevant HTML tag, plus a class of haupia-
and the name of the element.
For instance, a Haupia checkbox is a regular <input type="checkbox">
plus the class
haupia-checkbox
. More complex components might need additional wrapper or sibling elements.
(Code examples are given below.)
Themes
The default theme is built around a bunch of CSS variables, found at
the top of the stylesheet. These are easily modified to fit your site's
own palette, typography, and look-and-feel. For instance, you can
change the background color of the basic buttons by adjusting the value
of --haupia-button-background-color
to your preferred color.
License
Haupia is free to use, under the MIT license.
Buttons
The basic button can be used on a variety of HTML tags.
<button class="haupia-button">Button text</button>
<a href="somewhere" class="haupia-button">Button text</a>
<span class="haupia-button" role="button" tabindex="0">
Button text
</span>
<input type="submit" class="haupia-button" value="Button text" />
Button sizes and variants
Buttons can be made larger or smaller, and can take different variants (skins).
<button class="haupia-button haupia-button-large">
Large button
</button>
<button class="haupia-button haupia-button-secondary">
Secondary button
</button>
<button class="haupia-button haupia-button-small haupia-button-danger">
Small danger button
</button>
Form inputs
Checkbox
Switch
Like a checkbox, a toggle switch is also an on/off indicator, so it is treated as a checkbox.
<input type="checkbox" class="haupia-checkbox" />
<input type="checkbox" class="haupia-switch" />
Radio buttons
<input type="radio" class="haupia-radio" name="exampleRadio" value="exampleValue" />
Radio buttonbar
Radio buttons can also be presented as a bar of buttons.
<fieldset class="haupia-radio-buttonbar" role="toolbar">
<input type="radio" id="exampleRadio1" name="exampleRadio" value="exampleValue" />
<label class="haupia-radio-buttonbar-button" for="exampleRadio1">
Button Text
</label>
</fieldset>
Dropdown
<select class="haupia-select">
<option>Option 1</option>
<option>Option 2</option>
</select>
Text input
Textarea
<input type="text" class="haupia-input-text" />
<textarea class="haupia-textarea"></textarea>
Input group
An input group combines a text input with a button and/or some static elements into a single visual display.
<div class="haupia-input-group">
<span class="haupia-input-group-static">$</span>
<input type="text" class="haupia-input-text" />
<span class="haupia-input-group-static">.00</span>
</div>
<div class="haupia-input-group" role="group">
<input type="text" class="haupia-input-text" />
<input type="submit" value="Search" class="haupia-button" />
</div>
Disabled form elements
When disabled, form elements get a washed-out look.
Presentation
Alert
<div class="haupia-alert" role="alert">
I am a default alert.
</div>
<div class="haupia-alert haupia-alert-error" role="alert">
I am an error alert.
</div>
Dismissable alerts
Alerts can be dismissable; a click on the "x" icon will hide the alert.
<input type="checkbox" id="myDismissibleAlert"
class="haupia-close-button-checkbox" />
<label for="myDismissibleAlert"
class="haupia-close-button">
<span class="haupia-visually-hidden">
Dismiss this alert
</span>
</label>
Breadcrumbs
<ul class="haupia-breadcrumbs" role="navigation">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li>Not a Link 3</li>
</ul>
Loading spinner
<span class="haupia-spinner" aria-live="polite" role="status"><span>
Badge
A paragraph of text with a badge in it.
You can also use a badge to show a number:
<span class="haupia-badge">default badge</span>
<span class="haupia-badge haupia-badge-secondary">secondary badge</span>
Progress
This is a styled version of the progress
tag,
a visual meter.
(To show progress along a series of steps, see Progress List below.)
<progress class="haupia-progress" value="70" max="100"></progress>
Progress List
The progress list shows the current progress along a series of steps.
- Completed step
- Current step
- Future step
<ul class="haupia-progress-list">
<li class="haupia-progress-list-complete">Completed step</li>
<li class="haupia-progress-list-current" aria-current="step">Current step</li>
<li>Future step</li>
</ul>
Interactive controls
Tooltip
Hover over me to see a tooltip.
<div class="haupia-tooltip">
<p>I am the regular content.</p>
<aside class="haupia-tooltip-content" role="tooltip">
I am the tooltip content.
</aside>
</div>
Accordion
For content that collapses and expands.
Click me to expand/collapse
I am the accordion content.
I am the accordion content.
I am the accordion content.
An accordion with multiple panels:
Click me to expand/collapse
I am the accordion content.
I am the accordion content.
I am the accordion content.
Click me to expand/collapse
I am the accordion content.
I am the accordion content.
I am the accordion content.
Click me to expand/collapse
I am the accordion content.
I am the accordion content.
I am the accordion content.
<div class="haupia-accordion">
<details class="haupia-details">
<summary class="haupia-summary">
Click me to expand/collapse
</summary>
<div class="haupia-details-content">
I am the accordion content.
</div>
</details>
</div>
with header text that changes
Accordions can be set to have different header text when expanded vs. collapsed.
See More See Less
I am the accordion content.
I am the accordion content.
I am the accordion content.
<div class="haupia-accordion">
<details class="haupia-details">
<summary class="haupia-summary">
<span class="haupia-summary-content-closed">
See More
</span>
<span class="haupia-summary-content-open">
See Less
</span>
</summary>
<div class="haupia-details-content">
I am the accordion content.
</div>
</details>
</div>
with unstyled content
An "unstyled" accordion removes the bounding border and the inset on the text.
Here is some text content above the unstyled accordion.
Click me to expand/collapse
I am the accordion content.
I am the accordion content.
I am the accordion content.
Click me to expand/collapse
I am the accordion content.
I am the accordion content.
I am the accordion content.
Click me to expand/collapse
I am the accordion content.
I am the accordion content.
I am the accordion content.
// as above, but add class
// "haupia-accordion-unstyled"
// to the accordion.
Tabs
Tabs use radio buttons to control which tab is shown. Set the default tab's radio button to checked.
<div class="haupia-tabs" role="tablist">
<input type="radio" name="exampleTabs" value="1" id="exampleTab1" checked="checked" role="tab" aria-controls="tabpanel1">
<label for="exampleTab1" id="tablabel1">Tab 1</label>
<div class="haupia-tabs-content" id="tabpanel1" role="tabpanel" aria-labelledby="tablabel1">
Tab 1 content, shown by default
</div>
<input type="radio" name="exampleTabs" value="2" id="exampleTab2" role="tab" aria-controls="tabpanel2">
<label for="exampleTab2" id="tablabel2">Tab 2</label>
<div class="haupia-tabs-content" id="tabpanel2" role="tabpanel" aria-labelledby="tablabel2">
Tab 2 content
</div>
</div>
using "simple" variant
The "simple" variant gives the tabs a simpler display.
// as above, but add class "haupia-tabs-simple"
// to the outermost container
Typography
Heading
You can use any of the Haupia heading classes on any of the H1-H6 tags, depending on the desired visual appearance of a given heading.
H1 with class "haupia-h1"
H2 with class "haupia-h2"
H3 with class "haupia-h3"
H4 with class "haupia-h4"
H5 with class "haupia-h5"
H6 with class "haupia-h6"
H1 using class "haupia-h3" instead of "haupia-h1"
<h1 class="haupia-h1">Heading Level 1</h1>
Inside a block with class "haupia-type":
For convenience, you can also wrap a section with the class
haupia-type
. Any headings inside that section
will then automatically get Haupia's heading styling.
H1 with no class on it
H2 with no class on it
H3 with no class on it
H4 with no class on it
H5 with no class on it
H6 with no class on it
H1 using class "haupia-h3"
<div class="haupia-type">
<h1>Heading Level 1</h1>
</div>
Blockquote
I am a blockquote, used for quotes that are longer pieces of text.
<blockquote class="haupia-blockquote">
Blockquote text goes here.
</blockquote>
Lists
- Unordered List 1
- Unordered List 2
- Unordered List 3
- Ordered List 1
- Ordered List 2
- Ordered List 3
using "unstyled" variant
The unstyled variant removes any list-specific styling — useful when your items are semantically a list, but shouldn't appear as one.
- Unordered List 1
- Unordered List 2
- Unordered List 3
<ul class="haupia-ul">
<li>Unordered List 1</li>
<li>Unordered List 2</li>
</ul>
<ol class="haupia-ol">
<li>Ordered List 1</li>
<li>Ordered List 2</li>
</ol>
<ul class="haupia-ul haupia-ul-unstyled">
<li>Unordered List 1</li>
<li>Unordered List 2</li>
</ul>
Text alignment
Text aligned left.
Text aligned center.
Text aligned right.
H5 with "haupia-h5" and aligned right.
<p class="haupia-text-left">Text aligned left.</p>
<p class="haupia-text-center">Text aligned center.</p>
<p class="haupia-text-right">Text aligned right.</p>
Code block
<p>Code line 1</p>
<p>Code line 2</p>
<p>Code line 3 is really, really long and will likely be wider than the bounding box, because holy cats, is this a long line.</p>
<p>Code line 4</p>
<p>Code line 5</p>
<p>Code line 6</p>
<pre class="haupia-code-block">
<code>
Code example goes here
</code>
</pre>
Browser Support
What makes Haupia's code so simple is its extensive use of CSS custom properties (aka CSS variables) and CSS filters, so it works in any browser that supports these features (which is basically all modern browsers).
The close buttons inside dismissible Alerts use the :has
feature of CSS, which as of
May 2023 is not supported by Firefox and some older versions of Safari.
If those browsers are on your supported browser list, you should
avoid using dismissible Alerts, since clicking on the close button will not
close the component.
Accessibility
Haupia's listed APIs include as much accessibility support as HTML and CSS alone can provide. But Haupia is a CSS-only library, and full accessibility support for your page may sometimes require JavaScript. Please follow the WCAG guidelines.
Haupia provides a visible focus-visible
indicator for its components.
If you want this style to apply to all focusable elements on your page,
so that your page is visually consistent, add this CSS:
*:focus {outline: var(--haupia-focus-outline);}
*:focus-visible p {outline: var(--haupia-focus-visible-outline);}