A bold, dark portfolio homepage template for a photographer, built with Bootstrap 6. It includes a photo mosaic hero, tabbed portfolio with viewer dialog, live package estimator, reviews and a booking form.
How it works
The page lives in .mv-page, which sets data-bs-theme="dark" and re-maps --bs-primary-bg and --bs-control-checked-bg to amber.
- Navbar:
navbar lg:navbar-expandwith numbered links and a<dialog class="drawer drawer-end">panel on small screens. The script syncsaria-expandedon.mv-toggler. - Hero: the
[data-mv-month]line is filled with the next two month names, so "taking commissions" never shows a stale date..mv-mosaicis a grid of three.mv-framephotos with EXIF captions. - Work:
nav nav-underlinetabs (data-bs-toggle="tab") switch three.tab-panegrids. Each.mv-worktile is a button; clicking it opens#mv-viewer(dialog dialog-xl) withdata-mv-titleanddata-mv-meta. - Packages:
.mv-buildercombines.radiopackage cards (data-mv-price,data-mv-name) with.switchextras. The script sums them into[data-mv-total]. "Request this package" (data-mv-use) selects the same package in the booking Combobox. - About and clients: a framed photo,
chipgear tags and three quote cards. - Booking:
<form data-bs-validate novalidate>with a Combobox (data-bs-name="session"), a Datepicker on#mv-datelimited to dates from two days ahead up to one year, and a required textarea. Submit flags invalid fields with.is-invalid, then simulates sending and opens#mv-toast.
Customization
- Change
--mv-amber,--mv-bgand--mv-surfacein.mv-page(style.css), and the--bs-primary-*overrides beside them, to rebrand. - Swap fonts through
--mv-display,--mv-sansand--mv-monoplus the Google Fonts URL. - Edit prices with
data-mv-priceon each package radio and extra switch; the total updates automatically. - Add a tab by copying a
nav-itembutton and a matching.tab-pane; the.mv-work-gridlayout handles three or four tiles. - Replace the
setTimeoutin the booking submit handler withfetch()to your own endpoint. - The sample photos come from Unsplash; replace them with your own portfolio images.
Accessibility
A skip link targets #mv-main. Tabs use role="tab", aria-selected and aria-controls; portfolio tiles are buttons with descriptive alt text; the viewer is a native modal dialog with a labelled title. The estimator total is an output with aria-live, form errors appear next to their fields and the first invalid field gets focus. Image zoom and transitions are disabled under prefers-reduced-motion.
Bootstrap 6 notes
Built on Bootstrap 6.0.0-alpha.1, so alpha APIs can still change. Bootstrap 5 developers will notice btn-solid theme-primary instead of btn-primary, a Drawer navbar instead of navbar-collapse, Dialog instead of Modal, .radio and .switch instead of form-check, and data-bs-validate instead of needs-validation. Combobox, Datepicker and Chips are new Bootstrap 6 components. The Combobox keeps its choice after the form resets.