# Blue Web
Blue Web is the base library for [Blue React](https://bruegmann.github.io/blue-react) and [Blue Blazor](https://bruegmann.github.io/blue-react). This library builds heavily on top of [Bootstrap](https://getbootstrap.com/docs/) and also provides additional solutions in CSS and JavaScript.
## Use Blue Web
Install with NPM:
```
npm i blue-web
```
[](https://www.npmjs.com/package/blue-web)
## Implementation
If you have a React or Blazor project, you should use the components of [Blue React](https://bruegmann.github.io/blue-react) or [Blue Blazor](https://bruegmann.github.io/blue-blazor). Otherwise you can also write the markup of those components directly in HTML. Check out the examples in the docs to find out how.
For the JavaScript solutions you have to import the associated file. When installed using NPM, you can do it like this:
```js
import "blue-web/dist/js/dialog.js"
import "blue-web/dist/js/progress.js"
// ...
```
**Important:** Since 1.14.0 JavaScript files are compiled as ES modules. When you embed them in HTML using the `
```
JavaScript files are compiled as ES modules. This allows you to use import functions like this:
```html
```
## Customization and theming
Since Blue Web is based on Bootstrap, you can customize many things by overriding Sass or CSS variables. For more information, see the [Bootstrap documentation](https://getbootstrap.com/docs/5.3/customize/overview/). Blue Web also provides some additional variables that you can use and override. Take a look at [dist/styles/\_variables.scss](https://github.com/bruegmann/blue-web/blob/main/dist/styles/_variables.scss) to see all of them.
Here is an example of how to override variables using Sass:
```scss
// Override Bootstrap Sass variable
$primary: tomato;
// Override Blue Web Sass variables
$theme: orange;
$theme-dark: darken(orange, 10%);
// Stylesheet for Blue Web. Already contains Bootstrap.
@import "~blue-web/dist/style";
```
An example of how to override CSS variables:
```css
:root {
/* Override Bootstrap CSS variable */
--bs-body-font-family: "Inter", sans-serif;
/* Override Blue Web CSS variable */
--blue-sidebar-bg: #333;
}
```
## Buttons
Blue Web added some button variants to Bootstrap's default button styles. These variants are designed to be used in conjunction with the default Bootstrap button classes.
### `.blue-btn-soft-*`
```html
```
### `.blue-btn-plain-*`
A plain variant of Bootstrap's buttons. Always use together with `.btn`!
```html
```
### Button with icon
Blue Web enhances [Bootstrap's icon link helper](https://getbootstrap.com/docs/5.3/helpers/icon-link/#example) with the `.blue-btn-icon-wrapper`
class, enabling icons to be wrapped in a `span` element.
This simplifies the integration for Blue React and Blue Blazor by allowing icons to be passed as props more easily.
```html
```
### Button with icon only
Use `.icon-link` together with `.blue-btn-square` to adjust the padding, so the button is a square.
```html
```
## Collapse
Animated collapse using HTML `details`.
```html
❯
Collapse
Show something
```
Element with class `blue-collapse-chevron` will be rotated to `90deg` by default. But you can also customize the rotation target position with the CSS variable `--blue-collapse-chevron-rotate`:
```html
Collapse
❮
Show something
```
### Field group
```html
Field group header
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et
dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed
diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea
takimata sanctus est Lorem ipsum dolor sit amet.
```
### Combine with styling of Menu Item
```html
Parent
```
### Menu Item and Collapse grouped
`.blue-collapse-group` let's you group a collapse together with another UI element like a button that should come before the collapse summary.
```html
Collapse sub menu
```
---
```html
Collapse sub menu
```
## Container Grid
### `.blue-container-grid`
Adds container query support to Bootstrap's grid system. By default, Bootstrap's breakpoint classes only react to changes in the viewport width.
With container queries, you can apply breaks based on a custom container.
- [Read more about container queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries)
- [Read more about Bootstrap's grid system](https://getbootstrap.com/docs/5.3/layout/grid/)
```html
col-md-4
col-md-8
```
```html
col-md-4
col-md-8
This is a container grid. Resize the box around to see the effect.
```
## Header
Provided helper classes designed to be used inside a header.
```html
AppTitle
```
## Hover
### `.blue-opacity-hover`, `.blue-opacity-hover-content-active`, `.blue-opacity-hover-content-default`
With `.blue-opacity-hover` you can hide things by default and let them appear when the user hovers the area around it or focuses an element inside.
This way you can simplify the UI a bit and make controls disappear when they are not needed. On touch screens the elements will always be visible.
Usage:
```html
Hover here to see a button
```
### `.blue-d-hover`, `.blue-d-hover-content-active`, `.blue-d-hover-content-default`
`.blue-d-hover` is similar to `.blue-opacity-hover`, but the elements will disappear and appear with the `display` property.
It is ideal if you want to replace something with something else when the user hovers. On the example I used it to change the edit and delete icons from lineout to filled when hovering.
Usage:
```html
```
### `.blue-bg-hover`
Changes background color on hover.
```html
Hover to change background color
```
With CSS property `--blue-hover-bg` you can set the background color on hover:
```html
Hover to change background color
```
## Input group
Special variant of [input group](https://getbootstrap.com/docs/5.3/forms/input-group).
The whole group will have a focus ring when an inner input is focussed. And styling for `.input-group-text` is simplified.
### Search
This variant is especially useful for search input.
```html
```
### Intro
Styles for a login screen.
```html
Hello World
Here could be a sign in form.
```
## Menu Item
Styles for interactive elements in sidebar and in header area.
```html
```
### With icon
This is the same approach as in [Buttons](Buttons#button-with-icon).
```html
```
### Active state
```html
```
### Current state
```html
```
### Different icon for current
```html
```
### Current state horizontal
```html
```
### Combine with Collapse
Together with `.blue-collapse` and [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/details) you can create a collapsable sub menu.
Could be used inside the sidebar.
[Click here to go the example on the Collapse page](css/Collapse#combine-with-menu-item).
## Modal
Allows to use [Bootstrap Modals](https://getbootstrap.com/docs/5.3/components/modal/) but with the native dialog element and without the need of Bootstrap's JavaScript.
```html
```
### Offcanvas
Because [Bootstrap Offcanvas](https://getbootstrap.com/docs/5.3/components/offcanvas/) works quite similar, you can also use `.blue-modal` with that.
```html
```
### Modal in Offcanvas
```html
```
### Show dialog in main DOM layer
If you use `dialog.showModal()`, the dialog will be inside the top layer, above anything else on your page, also if other elements have an higher `z-index`. Use `dialog.show()` instead and it will be inside the main layer.
```html
This has a really high z-index. It should be over the dialog, when you open it with .show() and underneath it when
you open it with .showModal().
```
## Neumorphism SCSS utilities (Experimental)
Blue Web comes with `dist/neu.scss` containing some SCSS and CSS utilities to make it easy to apply shadow effects.
The effects can have some weird side-effects, that's why they are not included by default with `dist/style.scss`. You have to embed it yourself.
### Getting started
1. Import neu.css in your main SCSS file:
```scss
@import "~blue-react/dist/neu";
```
2. Apply the mixin "neu()" at the area you want to use it:
```scss
:root {
@include neu(#610dfd);
}
```
First parameter takes the areas's background color. As second parameter you can set the background color for inset.
### Utility classes
The notation looks like this: `.neu-shadow{-inset?}{-switch?}{-size}`
- Where `inset` is optional. When you set it, the box-shadow will be set to the inside.
- Where `switch` is optional. When you set it, the light and dark shadow colors will be switched. **Can only be used together with `inset`!**
- Where size is required and one of:
- `1` - distance and blur values multiplied with `.25`
- `2` - distance and blur values multiplied with `.5`
- `3` - distance and blur values multiplied with `1`
- `4` - distance and blur values multiplied with `1.5`
- `5` - distance and blur values multiplied with `3`
Format and the values are inspired by [Bootstrap](https://getbootstrap.com/docs/5.3/utilities/spacing/#notation).
### Combining classes
You can combine shadows with inset shadows like this:
```html
```
```scss
.bg-body {
@include neu($body-bg, $body-bg);
}
@include color-mode(dark) {
.bg-body {
@include neu($body-bg-dark, $body-bg-dark);
}
}
```
### CSS variables
You can use Neu's CSS variables and combine them like this:\
`style="var(--neu-shadow-3), var(--neu-shadow-inset-switch-1)"`
The notation is similar to the Utility classes.
### Examples
You can combine shadows to different soft effects.
```html
Neumorph card
```
## Popover
In combination with the [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API) and
[CSS Anchor Positioning](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_anchor_positioning)
you can create a dropdown menu without the need for custom JavaScript.
Use CSS property `position-area` to set where the popover should be relative to its anchor.
I recommend to use [the anchor position tool](https://chrome.dev/anchor-tool/) to find the right value.
### Fallback
Add `.blue-anchored-fallback` to the dropdown element and on not supported browsers, it will be displayed with an overlay over the whole page.
```html
Hello from popover!
```
### Anchoring helper classes
`.blue-anchor`, `.blue-anchored` and some other classes help you with some common stylings.
```html
Hello from popover!
Hello from popover!
Hello from popover!
```
## Scrollbar
### `.blue-scroll-shadow`
Adds shadow if area is scrollable.
```html
```
## Scrollspy
Uses CSS Carousel specs for a scrollspy only with HTML and CSS. Inspired by [Scroll Spy example on chrome.dev](https://chrome.dev/carousel/vertical/scroll-spy/).
Some browsers might not be supported. As of writing works best with Chromium based browsers.
### Example with List group
```html
Group 1
Item 1.1
Item 1.2
Item 1.3
Item 1.4
Group 2
Item 2.1
Item 2.2
Item 2.3
Item 2.4
Group 3
Item 3.1
Item 3.2
Item 3.3
Item 3.4
Group 4
Item 4.1
Item 4.2
Item 4.3
Item 4.4
```
### You can also make the scrollmarkers appear after
```html
Group 1
Item 1.1
Item 1.2
Item 1.3
Item 1.4
Group 2
Item 2.1
Item 2.2
Item 2.3
Item 2.4
Group 3
Item 3.1
Item 3.2
Item 3.3
Item 3.4
Group 4
Item 4.1
Item 4.2
Item 4.3
Item 4.4
```
### Handle overflow of group names
```html
Group number 1
Item 1.1
Item 1.2
Item 1.3
Item 1.4
Group number 2
Item 2.1
Item 2.2
Item 2.3
Item 2.4
Group number 3
Item 3.1
Item 3.2
Item 3.3
Item 3.4
Group 4
Item 4.1
Item 4.2
Item 4.3
Item 4.4
```
## Sidebar
### `.blue-sidebar-exception`
Prevents the default behaviour of closing sidebar after clicking an item.
### `.blue-sidebar-bottom`
With Sidebar Bottom, for example, a registered user can be displayed at the bottom left. Usable within ``.
### `.blue-sidebar-hidden-on-open`
The element is hidden as long as the sidebar is open.
### `.blue-sidebar-pseudo-hidden-on-open`, `.blue-sidebar-before-hidden-on-open`, `.blue-sidebar-afters-hidden-on-open`
Pseudo elements of element are hidden as long as the sidebar is open. `.blue-sidebar-before-hidden-on-open` hides
`::before`,`.blue-sidebar-after-hidden-on-open` hides `::after` and `.blue-sidebar-pseudo-hidden-on-open will` hide both.
### `.blue-sidebar-d-flex-on-open`
Alias: `.blue-sidebar-visible-on-open`
The element is visible (`display: flex`) as long as the sidebar is open.
### `.blue-sidebar-d-block-on-open`
The element is visible (`display: block`) as long as the sidebar is open.
### `.blue-sidebar-menu-horizontal-on-open`
Use this inside of the sidebar to make menus act like horizontal menus when the sidebar is open. Designed for the `IconMenuItem` component. But might be useful for other scenarios aswell.
### `.blue-sidebar-menu-vertical-on-open`
If you want to change direction inside of `.blue-sidebar-menu-horizontal-on-open` back to vertical, use `.blue-sidebar-menu-vertical-on-open`. Might be useful for dropdowns.
## Tabs
Tabs just with HTML and CSS, no JavaScript needed. The state is managed by the radio input elements.
The classes by Blue Web only provide styles for fundamental functionality.
```html
Tab content 1
Tab content 2
Tab content 3
```
### Bootstrap Tabs Nav style
You should combine them with `.nav.nav-tabs` and `.nav-link` by Bootstrap.
```html
Tab content 1
Tab content 2
Tab content 3
```
### Bootstrap Underline Nav style
```html
Tab content 1
Tab content 2
Tab content 3
```
### Bootstrap Underline Nav style customized
You can customize the look more by overriding the CSS variables coming from Bootstrap. Blue Web also added some additional CSS variables.
```html
Tab content 1
Tab content 2
Tab content 3
```
## Text and Icons
### `.blue-page-header` or `.page-header`
In previous versions of Bootstrap, `.page-header` was a class that could be used to add a border to the bottom of a page header.
Unfortunately his class was removed in Bootstrap 5, so it's now part of Blue Web CSS.
```html
Example headline
```
#### Heading levels
Combined with `h1`-`h6` elements or `.h1`-`.h6` classes, the border width changes.
```html
Example headline
Example headline
Example headline
Example headline
Example headline
Example headline
```
### `.blue-label`
```html
```
### `.blue-icon` or `.bi`
Vertically alignment, especially for Bootstrap Icons.
## Tooltip
### `.blue-tooltip`
CSS only solution for tooltips. For accessibility reasons, only wrap around interactive elements like buttons or links.
To use, add the `data-tooltip` attribute to the wrapping element.
```html
```
### `.blue-tooltip-up`, `.blue-tooltip-down`, `.blue-tooltip-start`, `.blue-tooltip-end`
Change the position of the tooltip. To be used together with `data-tooltip`.
```html
```
### `.blue-tooltip-content`
This is how you can customize the tooltip content with HTML.
```html
Somecustomcontenthere.
```
## Additional utility classes
Bootstrap already comes with a bunch of [utility classes](https://getbootstrap.com/docs/5.3/utilities/background/).
Blue Web adds some additional to them.
### `.m-last-0:last-child`
Sets `margin: 0` to last child.
Useful for creating a gap between items together with `mb-3`.
Inspired by Tailwind CSS class `last:m-0`.
### `.blue-empty-message`
Shows empty message if the element has no children.
Can be used for lists and such.
For localization you should override CSS variable `--message` dynamically.
```html
```
### `.blue-contain-paint`
Fixing border radius clipping.
```html
Child background destroys border radius of parent. βΉοΈ
Much better! π₯³
```
We automatically add it to Bootstrap's `.card`.
```html
My card
```
### `.blue-odd-bg`
Let you easily create striped items, like rows.
```html
Item 1
Item 2
Item 3
Item 4
```
You can set the background color using CSS variable `--blue-odd-bg`.
```html
Item 1
Item 2
Item 3
Item 4
```
## Actions
Combination of toolbar and a dropdown menu. Items in toolbar will only be shown if there is enough space.
Otherwise they will be visible in the dropdown menu. JavaScript detects if space is changing and rearranges.
### Demo 1: Use Menu Items of Blue Web and Dropdown with Popover and Anchor Positioning
```html
```
The JavaScript function `init` returns an object with the function `destroy()`. When you execute it, the `ResizeObserver` will be disconnected
and global event listeners will be removed. Try to click the button. It will destroy the actions from above.
```html
```
### Demo 2: Use Bootstrap Button Groups
```html
```
## Color Mode
Use `color-mode.js` for better support for [Bootstrap's color modes](https://getbootstrap.com/docs/5.3/customize/color-modes/).
The script automatically detects if the user uses light or dark mode and sets the `data-bs-theme` attribute to the document element (``). It also updates it if the color mode changes.
It also exports these functions:
- `getStored()` - Returns what is stored (`"light"`, `"dark"` or `null`).
- `getPreferred()` - Returns current color mode (`"light"` or `"dark"`).
- `set(colorMode: string)` - Let's you set the color mode.
- `init()` - Let's you reinitialize manually. Will automatically executed when the script loaded and when the color mode changes.
### Color Mode Switch
Example about, how you could create a color mode switch.
```html
```
## Dialog
These functions are meant as a nicer alternative to the native `alert`, `confirm` and `prompt` functions.
They are not meant to be used as a replacement for more complex modals.
### Functions
#### Verify
```html
```
#### Tell
```html
```
#### Ask
```html
```
#### Ask with default value
```html
```
#### Control dialog by ID
```html
```
## Input Splitted
Group of input fields. Perfect e.g. for entering PIN or TOTP.
### Demo
```html
```
### Disabled
```html
```
### Styling With CSS Variables
Even if `light-dom` isn't enabled, you can still use CSS variables to style the input elements.
```html
```
### Use Label
```html
```
### Use Label Without Shadow
```html
```
## Odometer
A Web Component that displays a numeric value with a smooth rolling animation β similar to a mechanical odometer or number counter.
Itβs designed for use in badges, notifications, dashboards, or any place where numbers change dynamically.
```html
```
### Styled as badge
```html
```
### Custom max number
```html
```
### Style based on change
When the value changes, the element will get attribute `data-change="up"` or `data-change="down"` depending on if the number increased or decreased.
This allows you to add styling based on the new state. After 3 seconds the attribute will be reset.
```html
```
### Change transition duration
You can change the duration using CSS variable `--bl-odometer-duration`. Default value is `0.4s`. In this example it is set to `5s`:
```html
```
## Overflow Detector
Generic utility to detect when an element's content overflows its bounds (horizontal text truncation).
Can be used for any element and any reaction to overflow β tooltips, title attributes, custom UI, etc.
### `OverflowDetector` class
Watches elements via `ResizeObserver` and calls a callback whenever the overflow state changes.
#### Methods
| Method | Description |
| --- | --- |
| `observe({ element, onChange })` | Start observing an element. `onChange(isOverflowing, element)` is called when the state changes. |
| `unobserve(element)` | Stop observing an element. |
| `checkAll()` | Re-check all observed elements. Useful after layout changes that `ResizeObserver` might not detect. |
| `destroy()` | Stop observing all elements and clean up. |
#### Example: Tooltip on truncated text
```html
```
### `isOverflowing` function
Standalone helper for one-time checks without setting up an observer.
```js
if (blueWeb.isOverflowing(myElement)) {
// element content is truncated
}
```
### Usage in frameworks
#### React
```tsx
import { OverflowDetector } from "blue-web/src/js/overflow-detector"
function MenuItem({ label }: { label: string }) {
const labelRef = useRef(null)
const [showTooltip, setShowTooltip] = useState(false)
useEffect(() => {
if (!labelRef.current) return
const detector = new OverflowDetector()
detector.observe({
element: labelRef.current,
onChange: (isOverflowing) => setShowTooltip(isOverflowing)
})
return () => detector.destroy()
}, [])
return (
)
}
```
#### Blazor (JS Interop)
```js
// In a .js file loaded by your Blazor app:
window.overflowDetector = new blueWeb.OverflowDetector()
window.observeOverflow = (element, dotNetRef) => {
window.overflowDetector.observe({
element,
onChange: (isOverflowing) => {
dotNetRef.invokeMethodAsync("OnOverflowChanged", isOverflowing)
}
})
}
```
## Progress
A "fake" progress bar that will appear fixed at the top of the page.
### Start and stop
```html
```
```html
```
### Add to custom element
You can customize the element further by setting a custom ID, parent element and position class name. This allows you to attach the progress element to some other element than the body.
```html
Add progress bar to this
```
## Read View
A Web Component that displays a read view of its content and allows the user to switch to an edit view.
### Demo
#### Basic usage
```html
Link
Click to edit the link
```
#### Disabled
```html
Link
This one is disabled
```
import Example from "$/components/Example.astro"
import ComboboxUsage from "$/recipes/select-list/combobox-usage.tsx"
## Select List
A Web Component to create a list with selectable items. Combine it an input element to create a search results UI.
### Demo
Take a look at the browser console. When you select an item, an event listener will log it.
```html
```
### Dropdown menu
Together with `popover` and CSS Anchoring, it's also useful to create a dropdown list.
```html
```
### React combo box demo
import UtilsDemo from "$/components/UtilsDemo.tsx"
## Utils
### Usage
You can import functions inidivually like this:
```js
import { startLoading } from "blue-web/dist/js/utils.js"
```
or like this:
```html
```
`utils.js` is provided as ESM, so you can use it as a module in the browser:
```html
```
### Required markup
Some of the util functions to show status information require to have some HTML elements available.
```html
```
### JavaScript Functions
## View Transition API
[View Transition API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API) is not a Blue Web API, but a native Web API provided by browsers.
It allows you to easily animate transitions between different UI states.
```html
```
## Layout
Blue Web offers a set of code to create a layout with a header, collapsible sidebar, and a main content area.
### Without sidebar
```html
```
### Adjust header logo size using CSS variable
Implementations for [React](https://bruegmann.github.io/blue-react/v10/component/HeaderTitle) and [Blazor](https://bruegmann.github.io/blue-blazor/components/header-title/props) provide components to set a layout header with a logo and app title.
By default the logo size is `2rem`. You can override that value with CSS variable `--blue-header-title-image-size`:
```html
```
If your logo has another width than height, you can also use a combination of `--blue-header-title-image-width` and `--blue-header-title-image-height`.
## Responsive Drawer
Responsive Drawers will be introduced in Bootstrap 6. Blue Web implemented ways that allow you to use it already today.
```html
Offcanvas
On larger screens, you will see this content immediately. On smaller screens, it will be hidden inside a
drawer and you can open it using a button.
```
## Typography
Since Blue Web builds on top of Bootstrap, you should also check out [their section about typography](https://getbootstrap.com/docs/5.3/content/typography/).
### Inter as font family
Blue Web is configured to use [Inter](https://rsms.me/inter/) with some preset font features. The required font files aren't included with Blue Web.
[Please take a look at the documentation by Inter](https://github.com/rsms/inter?tab=readme-ov-file#using--installing-inter) to find out how to install them.
As fallback, when Inter couldn't be loaded, the default font family setting by Bootstrap (`$font-family-sans-serif`) will be used, which is a native font stack that selects the best font-family for each OS and device.
### Extend font features
Font features are stored inside the CSS variable `--blue-font-feature-settings`. This allows you to extend them without overriding them:
```html