068

Boutique Hotel Template

£10

A boutique hotel website with a dark-green contents rail, a photographic room explorer, a walking-distance guide and a three-step enquiry journey. Designed for hotels, B&Bs, guesthouses, country retreats and wedding venues.

ScrollTrigger Lenis advanced
9 more details
tab-panelcrossfadescroll-revealparallaxkeyboard-navigationrange-inputanchor-scrollstickysmooth-scroll
Boutique Hotel Template - website template preview

This template reads better at your own screen size than in the frame below:

About this template

An expansive photographic website for boutique hotels, guesthouses and country retreats. Marlowe House is its worked example: fourteen rooms above Bath, a warm dining room and places to explore on foot. Large serif headings, a dark-green contents rail and richly scaled photography give the whole page the atmosphere of a house worth staying in.

Read the full template overview

Explore six rooms through photographs that move across a large exterior scene. Each selection brings its room description, rate and booking link into view. Broad dining photographs and an image-rich walking guide continue the visit before a three-step enquiry journey.

The site ships as editable HTML, CSS and JavaScript with local WebP photographs. Change its imagery, room details, palette and copy for a B&B, country house hotel, inn or wedding venue.

What's included

11 items
  • A dark-green monogrammed contents rail with numbered chapters beside an expansive photographic cover
  • A room explorer that keeps its selector and large photograph visible together on desktop, with a sticky swipeable room index on phones
  • Room selection by hover, click, touch and arrow keys, including Home and End
  • Smoothly interrupted room transitions and one-time text reveals that preserve their baseline
  • Large dining, breakfast, local-guide and house photographs
  • Walking-distance dial with immediate destination results, a live count and links into the photographic guide
  • A three-step enquiry journey: dates and room, guest details, then an editable review, with a live photographic stay summary
  • Fifteen locally bundled, graded WebP photographs and an editable source manifest
  • Complete stacked rooms without JavaScript and instant changes under reduced motion
  • Optional Lenis scrolling on the shared GSAP clock
  • Required-field and date validation, retained values when going back, and an explicit demonstration completion with no submission

Perfect for

6 use cases
  • Boutique hotels and country house hotels with several room types worth comparing
  • Bed and breakfasts, guesthouses and farm stays that want to sell on the rooms
  • Small inns and pubs with rooms, and restaurants with rooms
  • Wedding and event venues showing the house and the grounds
  • Design-led serviced apartment houses and members' clubs
  • Any bookable place sold on photographs, a walk from the door and a plain enquiry

How it works

4 sections

A photographic house visit

A fixed contents rail accompanies the cover, rooms, dining, walking guide and enquiry. Wide photographs and large serif headings carry the identity. Every section can be edited or removed independently.

Explore the rooms

Choose a room to bring its photograph, description, figures and booking link into view against the house scene. Changes glide smoothly between positions on desktop and stay within a fixed frame on phones. Keyboard navigation offers the same selection as pointer and touch.

The local guide and enquiry

Adjust the walking distance to see which places are within reach. The enquiry guides visitors through their room and dates, contact details and an editable review, while a photograph and summary reflect the chosen stay. It validates required fields and dates but does not send an enquiry or reserve a room.

Static and reduced-motion views

With JavaScript disabled the six rooms form a complete, readable sequence. With reduced motion enabled the controls still work, changes apply immediately and photographs remain still. Text remains visible when animation dependencies cannot load.

Plugins ScrollTrigger
Difficulty Advanced
Smooth scroll Lenis integration
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this template's demo, 9 September 2026. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Questions about this template

It's a hotel in the demo. What else does this design suit?

Anything bookable and sold on its rooms, its house and its location: a boutique hotel, a bed and breakfast or guesthouse, a country house hotel, a small inn or pub with rooms, a farm stay, or a wedding and event venue. The register is six rooms here, but each entry is a photograph, a caption, four figures and a floor, so they become six suites, six cottages or six event spaces by editing the text. Nothing in the layout says hotel except the words.

Does the enquiry form actually send anything?

No. This is a three-step demonstration: choose a room and dates, enter guest details, then review and edit the enquiry. Required fields and date order are checked, and values survive going back. Completion clearly says that nothing was sent or reserved. Connect it to your booking engine, Formspree, Netlify Forms or CRM before using it for real enquiries.

How do I add, remove or reorder the rooms?

Each room has a matching index entry and photo panel. Copy the pair and give them the same new key, then replace the photograph, floor label, description and figures. Add the room to the enquiry select as well. You can present suites, cottages or event spaces in the same explorer, with the house photograph providing the setting.

Can I use my own photographs, and what happens to the fifteen included?

Yes. The fifteen photographs are locally bundled WebP derivatives from Pexels and Unsplash. Replace the files or update the source manifest and regenerate them. The room photographs use a landscape 4:3 crop at 1400 by 1050, and the exterior is 1920 pixels wide. Keep the main subject within the centre of the crop so it also reads on phones.

Can I change the house photograph behind the rooms?

Yes. The exterior photograph appears both on the cover and behind the room explorer, giving the two sections a shared sense of place. Replace cover.webp with a broad landscape photograph of your property. Each room moves within the scene on desktop; on mobile it stays in place so its details remain easy to read.

Does the walking dial work on a phone and with a keyboard?

Yes. The walking guide uses a native range control, so a finger, mouse or keyboard can change the distance. Places within that radius receive the brass marker and full-strength photograph. Destination photographs remain visible on phones, making the guide useful as a visual introduction to the neighbourhood as well as a list of walking times.

I want a different accent colour and typeface. How much is there to change?

The palette and two font families are defined at the top of the stylesheet. Change the ivory grounds, ink, brass and dark dining surface together with their RGB values. Keep the pale labels on photographs and the cover scrim so text remains readable over your new images. The included contrast notes explain the intended use of each colour.

Paid template

Purchase to unlock the code.

Buying Boutique Hotel Template opens the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects.

£10 Standard license, unlimited projects

Browse free effects

Documentation

Quick Start

1. Upload the folder. index.html, assets/style.css, assets/script.js (or assets/script.min.js) and assets/img/ are the whole site. Any static host will do.

2. Check the <head>. Three things must stay, in this order:

Code snippet omitted: it ships with the download.

That one-line script must stay synchronous and stay in <head>. It is what stops every reveal target painting visible for a frame and then flashing to zero. data-cfasync="false" stops Cloudflare Rocket Loader deferring it, which would bring the flash back on the live site only.

3. Keep the scripts before </body>:

Code snippet omitted: it ships with the download.

4. Swap the fifteen photographs and rewrite the copy. Everything else is optional.


Using It With Your Own Design

The page is one long printed sheet, so the fastest reskin is to decide what your place is and let the copy do the work. Four changes carry most of it:

  • The name and the colophon. The wordmark in the rail, the h1 on the cover in the .cover__name heading, and the one-line colophon under it.
  • The token block. Nine solids at the top of assets/style.css, each with its RGB triple. Every rule, dimmed label, floor label, scrim and focus ring on the page is one of them at another alpha.
  • The photographs. Drop your own files into assets/img/ with the same names, or edit assets/img-manifest.json and re-run the bake.
  • The register. Six rooms, each one index row plus one stage entry, joined by a key such as garden. Copy both blocks and rename the key.

Nothing in the layout says "hotel" except the words, so the same page becomes a B&B, a country house hotel, a small inn or pub with rooms, a farm stay or a wedding venue by editing the copy and the room names.


Sections and their options

Each section is initialised by its own function and every one returns early when its markup is missing, so you can delete any section from index.html without touching the JavaScript.

Section Hook What you can change
Cover .cover / #top The two name copies, the colophon, and the photograph. The photograph's height is .cover__media in CSS; the paper name is clipped to it by script.
The register [data-reg] / #rooms Each [data-reg-tab="key"] index row is joined to a [data-reg-panel="key"] entry. Copy a pair to add a room. Each panel carries an opaque floor label and a landscape photograph.
The table #table Plain markup: the supper list with prices, the hours, the note and the two photographs. The [data-drift] image drifts on scroll.
Around #around Each li.around__row carries data-min (the walk time) and a brass dot, a minute, a place, a line and an optional small photograph. The dial's range is min/max/step/value on [data-dial-range].
The house #house Five .house__fact definition rows and the figure row. The photograph is sticky beside them on desktop.
Enquire #book / [data-book-form] The rate line, the contact, and the form fields. The room <select> options must use the same keys as the register if the "Book this room" links are to set them.

The register

The six rooms begin life as six complete entries in the markup, so with JavaScript off they stack as a plain list of rooms with their own plates, captions and figures. With motion allowed the section adds .is-live and the entries stack in one grid cell to become a tablist.

  • Inputs. Pointer hover on a fine pointer, click and tap, and the arrow keys with Home and End over a roving tabindex (aria-selected and tabindex move with the selection; the inactive panels take inert).
  • The transition. Opacity changes and the panel's position ease from their current values. Rapid input retargets the current transition without jumping to the previous endpoint. Desktop positions are in the positions array in initRegister; mobile uses a fixed position. Keep positions between 0 and 9 with the default 91% panel width to retain clearance inside the scene.
  • The house scene. .reg__house holds the large exterior photograph. Each room has a .reg__floor label. Replace assets/img/cover.webp to change the exterior in both the cover and explorer. No SVG elevation is required.
  • Book this room. Each entry carries a link with data-book-room="<key>". It sets the value of the enquiry's room <select> and the ordinary in-page scroll carries the visitor to the form.

The cover

The name is a single heading over the exterior photograph. A dark CSS scrim keeps it legible. Its entrance changes opacity only; scroll reveals likewise run once and never reset or translate text when the visitor reverses direction.

The walking dial

#around hides its dial until the script shows it, so with JavaScript off the dial is absent and every row shows at full strength. The dial is a native <input type="range">: a finger drags it, a tap jumps, and the arrow keys, Home and End move it a step. Each update toggles .is-in / .is-out on the rows whose data-min is inside or beyond the radius — the brass dot, the brass minute and the full-strength photograph for the ones inside, a hairline and a dimmed photograph for the rest — and writes the count out in [data-dial-count].

The enquiry journey is not wired

The enquiry uses three data-step fieldsets: stay, guest details and review. initBook owns progression, back and review-edit controls, validation and the live photograph. Inputs keep their values when changing steps. Room links from the explorer update the select and dispatch change so the summary stays current. Dates use local calendar values; departure must follow arrival. Required fields and email validity are checked before advancing. Review values are inserted as text, including the optional guest note.

The final action completes a demonstration only. Nothing is transmitted or reserved. Connect the final submit branch to your booking engine or enquiry endpoint to collect real requests, and handle server validation and responses. Without JavaScript all input fieldsets remain readable; the interactive actions are hidden. Reduced motion keeps all steps usable without the transition.

The dark sidebar has numbered section links, an active dot and a stay action. Mobile uses the existing keyboard-accessible drawer. The room index and image share a desktop grid row; below 961px the index is a sticky horizontal scroller. The walking scale's labels use the same 10px endpoint inset as its 20px thumb. A live result list directly beneath the slider shows every destination within reach, with links to the photographic guide. Its reserved height prevents the guide moving when results change.

Palette

Nine solids and their --*-rgb triples at the top of assets/style.css: the paper #F3EEE4, the register band #E9E2D4, the ink #1D1B18 with two dimmed steps, the brass accent #865D1E, the night band #1E1B17, and the lifted accent #D8A657 that exists only for the band. Repaint them and the site reskins.

Measured as used, composited, at the size it is used:

Pair Ratio Notes
ink on paper 14.9:1 the name, chapter heads
ink-dim on paper 6.7:1 body copy, captions
ink-faint on paper 5.2:1 12px labels — the floor
ink-faint on the register band 4.95:1 the same labels on paper-2
brass on paper / on the register band 5.05:1 links, figures, the floor label
paper on brass fill 5.05:1 the Book now bar, the Send button
paper on night 14.9:1 the dining band
paper-dim / paper-faint on night 9.4:1 / 7.1:1 band body and labels
brass-lift on night 7.8:1 menu prices, the band's one accent

Brass is never set as text on the night band (it measures 2.1:1 there; the lift exists for it) and never sits on a photograph. Over the cover photograph the light name is --paper against a dark scrim. The cover scrim darkens the photograph beneath the text; retain it with replacement imagery.

Type: Gilda Display (display, 400) and Overpass (text, 400/500/600). The name is the page's largest object; chapter heads sit around a 3.4:1 ratio against body copy, and the label at 12px is the only small type.


Images

Fifteen bundled photographs in assets/img/, about 2MB in total, all WebP graded as one set: saturation 0.80–0.86 and a few degrees toward red, with a small brightness lift per image. The originals are never redistributed.


Accessibility

Keyboard: the register is a real tablist — click, the arrow keys, Home and End all select a room, and the active tab and panel carry aria-selected and inert correctly. The walking dial is a native range input, so the keyboard path is built in. Every link, button, field and the room <select> are real controls with a visible focus ring; the enquiry's nights count and the dial's count are announced through live regions, so no state is only visual.

The phone menu is a <button> that reports aria-expanded, moves focus into the rail when it opens, closes on Escape or on the scrim, returns focus to the button that opened it, and stops Lenis while it is open.

Reduced motion is a complete static page: the reveals are restored, the register and the dial still work with every change applied instantly, and the band photographs are left still.

Without JavaScript the head gate is removed and the page is a plain printed document: the six room entries stack complete with their plates, captions and figures, the dial is hidden and every row shows at full strength, the cover name sits on the paper, and the rail is a working list of in-page links. The same is true if the CDN is blocked — initTemplate takes has-js back off so nothing is left hidden.


Dependencies and teardown

GSAP 3.15.0 (core and ScrollTrigger) and Lenis 1.3.17, both from CDN. The script's one gsap.context() owns every animation and ScrollTrigger; the matchMedia branch returns a cleanup that removes the listeners it added and destroys its own Lenis instance, leaving any host Lenis in place. Lenis can be switched off per page with data-smooth="off" on <html> or ?smooth=off in the URL.

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.

Your cart

Your cart is empty

The Vault £99

Everything in the catalogue, plus everything we release next.