@htmlbricks/hb-layout-mobile
v0.76.5
Published
Mobile layout with optional offcanvas sidebar navigation, top navbar, main page slot, optional cookie-law banner, and footer. The host is fixed to the viewport height (100dvh). By default the main area scrolls and includes the cookie banner and footer aft
Downloads
8,119
Readme
hb-layout-mobile
Category: layout · Tags: layout, shell, responsive · Package: @htmlbricks/hb-layout-mobile
Overview
hb-layout-mobile is a mobile-first application shell: optional offcanvas navigation (hb-offcanvas + hb-sidebar-desktop), a top hb-navbar, a primary page slot, an optional hb-cookie-law-banner, and hb-footer. It forwards navbar, footer, and navigation-related custom events to the host.
The host element is a fixed-height viewport column (100vh / 100dvh, overflow: hidden). The inner .hb-layout-mobile__shell is a flex column that stacks navbar, scrollable page region, and—depending on mode—cookie banner and footer.
Scroll modes
- Default (
single_screenoff or"no"): The main band (partpage) scrolls vertically. Inside it, the slot sits in a flex column with the cookie banner and footer so the slot grows when content is short, keeping the footer at the bottom of the scroll area (see.hb-layout-mobile__page--footer-insidein styles). Whenfooter.typeis"auto", the embedded footer uses theregularsize. single_screenon (any string except"no", or boolean true): Cookie banner and footer sit outside the scroll area at the bottom of the shell; only the page slot scrolls. Whenfooter.typeis"auto", the footer uses thesmallsize.
If you embed the host in a sized container instead of the full viewport, give ancestors a defined height and set height: 100% on hb-layout-mobile so the flex chain resolves.
Dependencies
The bundle registers nested packages (see extra/docs.ts): hb-footer (with hb-contact-item), hb-offcanvas (with hb-sidenav-link, hb-sidebar-desktop), hb-navbar (with hb-dropdown-simple), hb-cookie-law-banner, and hb-sidebar-desktop. Nested components ship their own Bulma scopes; theme tokens on the document still apply where shared.
Styling
Host and layout (SCSS)
styles/webcomponent.scss pins :host to full dynamic viewport height, hides overflow, and uses flex for the shell. The page area uses overflow-y: auto where scrolling applies. Bootstrap Icons are loaded for nested UI. styles/bulma.scss forwards Bulma flex helpers and host-scoped theme tokens so the shell can align with the Bulma variable system.
Theme variables (--bulma-*)
Set public Bulma CSS variables on :root / body (or any ancestor) so nested shadow roots that read them stay on-brand. Documented in extra/docs.ts:
| Variable | Role |
|----------|------|
| --hb-layout-navbar-background | Optional hb-navbar background (set on this host, hb-layout, or an ancestor). |
| --hb-layout-sidebar-background | Optional hb-sidebar-desktop background in offcanvas / shell. |
| --bulma-scheme-main | Default surfaces inside nested chrome. |
| --bulma-text | Primary text in navbar and footer. |
| --bulma-navbar-background-color | Bulma token consumed by hb-navbar (after optional layout / --hb-navbar-background-color). |
| --bulma-scheme-main-bis, --bulma-scheme-main-ter | Default hb-sidebar-desktop host background chain when layout sidebar override is unset. |
| --bulma-navbar-item-color | Navbar links and controls. |
| --bulma-footer-background-color | Footer background when hb-footer is used. |
| --bulma-link | Interactive accents (dropdowns, links). |
See Bulma CSS variables.
CSS parts
| Part | Description |
|------|-------------|
| container | Outer flex column stacking navbar, page, and (in single-screen mode) fixed cookie/footer. |
| navbar | Wrapper around hb-navbar for shell alignment. |
| page | Main column: scrollable viewport for content (and in default mode, cookie + footer inside the same scroll stack). |
| footer | Wrapper around the embedded hb-footer. |
HTML slots
| Slot | Description |
|------|-------------|
| nav-header-slot | Rendered in hb-offcanvas header span (only when navlinks is non-empty). |
| nav-left-slot | Forwarded to hb-navbar left-slot. |
| nav-center-slot | Forwarded to hb-navbar center-slot. |
| nav-right-slot | Forwarded to hb-navbar right-slot. |
| page | Primary content between navbar and footer/cookie stack. |
Custom element
hb-layout-mobile
Attributes (HTML)
Web component attributes use snake_case and string values. Objects and arrays must be JSON strings. Booleans from HTML are typically "yes" / "no" (this repo’s convention); some props also accept "true" / "false" where noted.
| Attribute | Description |
|-----------|-------------|
| id | Optional host identifier (typed on Component). |
| style | Optional inline style string (typed on Component). |
| company | JSON: company / brand payload for navbar and footer (ICompany). |
| contacts | JSON: footer contacts (IContacts). |
| socials | JSON: footer social links (ISocials). |
| navlinks | JSON: INavLink[]. When the array is non-empty, hb-offcanvas is rendered and the navbar shows the menu control; when empty or omitted, offcanvas is omitted and noburger is set on the navbar. |
| sidebar | JSON: offcanvas chrome — title, logo, type, optional enablefooter, enablethemeswitch ("yes" / "no" / "false" / empty). Passed through to hb-offcanvas / sidebar where used. |
| usermenu | JSON: IUserMenu for the navbar avatar dropdown. |
| pagename | Active navigation key for offcanvas (navpage on hb-offcanvas). |
| page_title | Navbar brand text (overrides company.siteName when set). |
| footer | JSON: { type?: "auto" \| "small" \| "regular" \| "large"; disable_expanding_small?: boolean }. Defaults to { type: "auto", disable_expanding_small: false } when coerced from string. |
| columns | JSON: IColumn[] for hb-footer. |
| policies | JSON: IPolicies[] for hb-footer. |
| cookielaw | "yes" / "true" (and other typed literals) — part of cookie banner visibility. |
| cookielawuri4more | Policy link URI string for the cookie banner. |
| cookielawlanguage | Language string for the cookie banner. |
| cookielawallowdecline | "yes" / "true" / "no" / "false" — banner decline behavior. |
| single_screen | String "no" disables single-screen mode; any other non-empty string enables it (coerced to boolean). Controls fixed footer/cookie vs scrolling layout (see above). |
| i18nlang | Language code passed into nested widgets (e.g. en, it). |
| i18nlanguages | JSON array { code, label }[] or string — language options for the offcanvas/sidebar path. |
Cookie banner visibility
hb-cookie-law-banner is rendered when any of the following holds: cookielaw is "yes" or "true", cookielawallowdecline is "yes" or "no", cookielawlanguage is a non-empty string, or cookielawuri4more is a non-empty string. The banner receives language from cookielawlanguage or i18nlang, plus allowdecline and cookielawuri4more.
Events
Custom events bubble from the host as declared in types/webcomponent.type.d.ts:
| Event | detail |
|-------|----------|
| offcanvasswitch | { isOpen: boolean } — from offcanvas or navbar menu switch. |
| pageChange | { page: string } — offcanvas page selection. |
| navbarDropDownClick | { key: string } — navbar dropdown entry. |
| footerClick | { elClick: string } — footer interaction key. |
| navbarSlotClick | { side: "left" \| "right" \| "center" } — navbar slot area click. |
| languageChange | Same shape as hb-sidebar-desktop languageChange (e.g. { code: string }). |
| themeChange | Same shape as hb-sidebar-desktop themeChange (theme preference). |
Usage notes
- Navigation icons:
navlinksentries use Bootstrap Icons names without thebi-prefix (e.g.house-door), consistent with other layout/nav components. - JSON props: At runtime,
footer,sidebar, andcompanymay be parsed from JSON strings in effects when passed as strings from attributes.
TypeScript (types/webcomponent.type.d.ts)
import type {
IContacts,
ISocials,
ICompany,
IColumn,
IPolicies,
} from "../../footer/types/webcomponent.type";
import type { IUserMenu } from "../../navbar/types/webcomponent.type";
import type { INavLink } from "../../sidenav-link/types/webcomponent.type";
import type { Events as SidebarDesktopEvents } from "../../sidebar-desktop/types/webcomponent.type";
export type I18nLanguageOption = { code: string; label: string };
export type Component = {
id?: string;
style?: string;
socials?: ISocials;
contacts?: IContacts;
company?: ICompany;
navlinks?: INavLink[];
pagename?: string;
page_title?: string;
usermenu?: IUserMenu;
cookielaw?: "yes" | "true" | "no" | "false" | null | "" | undefined;
columns?: IColumn[];
single_screen?: boolean;
cookielawuri4more?: string;
cookielawallowdecline?: "yes" | "true" | "no" | "false" | null | "" | undefined;
cookielawlanguage?: string;
sidebar?: {
title?: string;
logo?: string;
type?: string;
enablefooter?: "yes" | "no" | "false" | null | "" | undefined;
enablethemeswitch?: "yes" | "no" | "false" | null | "" | undefined;
};
footer?: {
type?: "auto" | "small" | "regular" | "large";
disable_expanding_small?: boolean;
};
policies?: IPolicies[];
i18nlang?: string;
i18nlanguages?: I18nLanguageOption[] | string;
};
export type Events = {
offcanvasswitch: { isOpen: boolean };
pageChange: { page: string };
navbarDropDownClick: { key: string };
footerClick: { elClick: string };
navbarSlotClick: { side: "left" | "right" | "center" };
languageChange: SidebarDesktopEvents["languageChange"];
themeChange: SidebarDesktopEvents["themeChange"];
};Minimal HTML example
<hb-layout-mobile i18nlang="en"></hb-layout-mobile>