016
AI ready Refreshed

Holiday Let Template

£29 View live demo or the whole Vault, £79.20

Includes the original v1 design as a separate download.

A seven-page site for a small collection of holiday cabins, cottages or glamping units: each stay has its own page and colour, a who's-coming filter reshapes the comparison, and a drag-across-nights calendar prices every night per cabin.

ScrollTriggerFlip Lenis advanced
14 more details
drag-interactionflip-layoutaccessible-filteringrange-inputcrossfadeclip-path-revealparallaxscroll-revealinteractive-mapsvg-route-drawingurl-statekeyboard-navigationview-transitionssmooth-scroll

Updated

About this template

A seven-page site for a small, owner-run collection of holiday lets, worked through as Scar Top: three cabins with wood-fired tubs on a hill farm above Malham in the Yorkshire Dales.

Read the full template overview

The design is colour-led. One acid colour appears only as solid bars, name plates on photographs and the Book button, every heading is set in wide-tracked capitals, and each stay owns a colour of its own that follows it from the home page's split rows to its column on the stays page, its tab on the calendar and its rows in the rate table.

Every page has something to handle. The home hero swaps to whichever cabin's plate you choose, the stays page folds away the cabins that do not suit your guests, dogs and access, each cabin page has a slider that walks through a day there from arrival to checkout, the booking page is a drag-across-nights calendar with a diary and rate table per cabin, and the area page draws real walking routes from the door on a street map.

To make it yours, rename the units, repaint the three unit colours, replace the photographs and edit the diary block at the top of the script. Duplicate a cabin page to add a unit.

Holiday Let Template - website template preview

What's included

13 items
  • Seven plain HTML pages: home, the stays compared, one page per cabin, dates and rates, and an area guide
  • Colour per unit: each stay's colour token drives its split row, comparison column, calendar panel, tab and table header
  • Home hero cabin chooser: the three name plates on the photograph swap the hero to that cabin and retarget its call to action
  • Who's coming filter on the stays page: guests, dogs and step-free access fold non-fitting cabins to a narrow colour bar, with a designed empty result
  • A day at each cabin: a native range slider, hour marks and mouse-drag on the photograph step through five photographs from arrival to checkout
  • Drag-across-nights calendar per cabin: taken nights stop the range, every night is priced on its own season, minimum stay and changeover days are checked live
  • Unit switcher on the booking page recolours the calendar, swaps its photograph and loads that cabin's diary and cleaning fee
  • Links such as book.html?unit=peat-house&from=2026-11-06 open the calendar on that cabin with the weekend already chosen
  • Enquiry form prefilled from the chosen dates, honest about being an unwired front end
  • Walks map on MapLibre and OpenFreeMap tiles with three routes drawn along the real footpaths from the farm
  • Draggable photo strip, house rules, FAQ, and getting-here directions
  • Readable with JavaScript off: plates become links, the day becomes a captioned sequence and the calendar shows a static month
  • Bundled photography baked to one grade: licensed stock for the walks and area, generated images for the cabins, owners and farm

Perfect for

5 use cases
  • Glamping sites with a handful of pods, bell tents or huts
  • Holiday cottages and cabin rentals let directly by the owner
  • Shepherd's huts, treehouses and farm stays
  • Small lodges or B&Bs with a few distinct rooms
  • Any small rental business that wants each unit to have its own identity and its own availability

How it works

5 sections

Units and colour

Each stay is marked up with a data-unit attribute, and a single rule per unit sets the colour token every component reads. The split rows, stays columns, calendar panel, tabs and table headers all pick it up, so adding a fourth cabin is a new token, a new rule and the markup for its row, column and tab.

The cabin chooser and the stays filter

The hero plates are native toggle buttons that crossfade the photograph and update the call to action; without JavaScript they are plain links. The stays filter is a normal form of radios and a checkbox. Each column carries its capacity, dog allowance and access as data attributes, and the layout change is animated as one measured transition so the page below does not jump.

The calendar

Availability and rates are a commented diary per cabin at the top of the script, with minimum stay and changeover days as plain constants. A range is grown from the first night and cannot be drawn across a taken night, so there is nothing to reject afterwards. Mouse drag, tap then tap, and arrow keys with Enter all move the same selection, and a polite live region narrates the keyboard path.

The walks map

The area page uses MapLibre GL with OpenFreeMap's no-key tiles. Each walk is stored as a list of coordinates taken from a footpath router, drawn on request and fitted to the screen. Wheel and one-finger touch keep scrolling the page, and with no WebGL the map is replaced by a link to the area on OpenStreetMap.

Fallbacks

Every page is complete without JavaScript or with the CDN blocked. Under reduced motion the chooser, filter, slider and calendar keep working with instant changes, and page-to-page navigation uses a short cross-document fade only where the browser supports it.

Plugins ScrollTrigger, Flip
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 (7 pages, lowest score shown), from the latest scan. 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

Which businesses can use this holiday let template besides cabins?

It is built for any small collection of units that each deserve their own page and diary: glamping sites with pods or bell tents, holiday cottages, shepherd's huts, treehouses, farm stays and small lodges or B&Bs with distinct rooms. Scar Top's three cabins are the worked example; rename the units, swap the photographs and repaint the unit colours.

How do I remove a unit?

Delete its cabin page, its links in the navigation and footer, its home plate and colour row, its stays columns and table column, its booking tab and its diary entry. Every feature reads the units present in the markup, so nothing else needs changing, and the colour token can stay or go.

How do I add a page for another unit?

Duplicate a cabin page to add a unit. Copy one of the three cabin pages, rename it, change its data-unit attribute so it takes the new unit's colour, and replace its photographs, day sequence, facts, rates and Book link. Then add the unit to the navigation, home plates, stays columns, booking tabs and the diary in the script.

Is the calendar a real booking system?

No. Availability, rates, cleaning fees, minimum stay and changeover days are arrays and constants at the top of the script, with no backend or channel manager behind them. It shows what is free and what a stay would cost, then hands the visitor to an enquiry. Keeping the diary current is a manual edit, or you can generate it from your own system.

Does the enquiry form send anything?

No, it is an unwired static front end. It collects the cabin, arrival and leaving dates, name, email, guests, dogs and a note, then shows a ready-to-send confirmation without sending it. Connect it to Formspree, Netlify Forms, your booking inbox or your CRM, and change the visible confirmation text, before taking real enquiries.

Can I move the map and the walks to my own location?

Yes. Change the farm pin's coordinates and replace the three routes with your own coordinate lists, taken from a footpath router or a GPX file, then rewrite each walk card's distance and time to match. The tiles come from OpenFreeMap and need no API key or account.

Are the cabins, owners and photographs real?

No. Scar Top, Ellen and Rob Hartley, the three cabins, their prices and the bookings are fictional, though Malham and its walks are real. The walking and area photographs are licensed stock; the cabins, the owners, the farm and night scenes and the Cove are AI-generated images. Replace them with your own photographs before launch.

Paid template

Purchase to unlock the code.

Buying Holiday Let 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. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

£29 Standard license, unlimited projects

Browse free effects

Or the whole library: the Vault, £79.20, one payment.

Documentation

Quick Start

Upload the folder to any static host and open index.html. Keep the seven HTML files beside assets/ so relative links keep working. There is no build step, framework or package to install.

Pages load normally. In browsers that support cross-document view transitions the change between pages is a short crossfade (off under reduced motion); elsewhere it is an ordinary page load.

GSAP, ScrollTrigger, Flip (stays page) and Lenis load from a CDN, MapLibre GL loads on the area page only, and the fonts (Reddit Mono and Reddit Sans) come from Google Fonts. Images, styles and the script are bundled locally.

Using It With Your Own Design

  1. Units. Rename Limekiln, Peat House and The Fold in the pages and in DIARY at the top of assets/script.js. Each unit is marked up with data-unit="limekiln" (and so on); keep those keys in step with the diary.
  2. Colour. Repaint --limekiln, --peat and --fold (one per unit) and, if you like, --acid, --ground and --ink at the top of assets/style.css (see Palette).
  3. Photographs. Replace the files in assets/img/ at the same names and shapes (see Images and Credits). The cabin photographs ship as flat colour placeholders named for the picture each slot needs.
  4. Availability and rates. Edit the diary block at the top of assets/script.js (see Booking).
  5. Cabin pages. Each unit has its own page (limekiln.html, peat-house.html, the-fold.html). Duplicate a cabin page to add a unit (see Adding a unit).
  6. The map. Move the pin and replace the routes (see Walks map).
  7. The enquiry form. Connect it before going live (see Booking).

Everything visual lives in assets/style.css; everything interactive lives in assets/script.js, one function per feature that returns early when its markup is absent. Delete a section or a page and the rest keeps working; remove its links from the nav and footer.

Pages and Configuration

File Content
index.html Hero with the unit chooser plates (the first unit is chosen on load), the split intro, one colour row per unit, the night band, the owners and the next free weekends
stays.html The three units side by side over their colours, the who's-coming filter, one colour column per unit, a comparison table and what every unit has
limekiln.html, peat-house.html, the-fold.html One page per unit, each in its colour: photograph and plate, essentials, the day slider, a draggable photo strip, the spec list, that unit's rates, a Book link with ?unit= and links to the other units
book.html Unit switcher, the drag-across-nights calendar, the live quote, the season table and the enquiry form
area.html A colour block beside the photograph, getting here, the walks map, dogs, eating and drinking, house rules and questions

Navigation

The acid strip and nav are repeated at the top of each page. Mark the current link with aria-current="page". Below 1080px the links move into a native <details> menu.

Unit chooser ([data-hero], [data-pick])

Each plate holds a toggle button and a fallback link. The button's data-pick names the unit's data-frame photograph, data-line is the sentence shown in the hero card and data-href is where the card's button then points. One plate is always chosen: mark the first with aria-pressed="true" (and is-on on its fallback link) and leave its frame visible; the others start hidden.

Colour rows

Each row is an <article class="quilt__row" data-unit="...">; rows alternate photograph sides automatically. Images marked data-drift move a little against the scroll.

Who's coming ([data-who], [data-col])

Each column carries data-sleeps, data-dogs (how many dogs are allowed) and data-stepfree="true|false". The form's guests, dogs and stepfree fields are compared against them; cabins that do not fit fold to a colour bar, and [data-none] is shown when nothing fits. Rows of the comparison table with data-row="sleeps|dogs|stepfree" are highlighted when that criterion is in use.

A day at the unit ([data-day-root])

Five <figure data-day> photographs, a range input with max set to the number of steps minus one, and a <button data-mark> per step (--i is its index and --n the last index, so it sits under the slider thumb). The time and caption for each step are the <li data-time> items in [data-day-data]. Add or remove steps by changing all four together. With a mouse, dragging across the photograph also moves through the day.

Adding a unit

Duplicate a cabin page to add a unit: copy the-fold.html to, say, the-byre.html, set data-unit="the-byre" on its <main> so it takes that unit's colour, and replace its photographs, day sequence, facts, spec list, rates and the ?unit= in its Book links. Then add the unit everywhere it is listed: a nav and footer link on every page, a hero plate and colour row on the home page, a hero column, filter column and table column on the stays page, a tab on the booking page, a diary entry in DIARY, and a colour token with its [data-unit] rule (see Example). Each cabin page lists the others at its foot; add the new one there too.

Walks map ([data-walks])

In initWalks() in assets/script.js, FARM is the pin as [longitude, latitude] and ROUTES holds one coordinate list per walk, keyed to the data-walk buttons. The demo routes were taken from the OpenStreetMap foot router (https://routing.openstreetmap.de/routed-foot/route/v1/foot/<from>;<to>?overview=full&geometries=geojson); a GPX export from your own walk works as well. Rewrite each card's distance and time to match.

Palette

Token Value Use
--ground #E7E6E0 limestone Page ground
--surface #D9DED4 Pale blocks: split intro, filter bar
--ink #1D2A26 Text on the ground and on acid
--acid #D7F23A Strip, plates, Book buttons, chosen nights. A fill, never text on the ground
--cream #F2F0E8 Text on unit colours
--limekiln #A9442A Unit one
--peat #3E5A39 Unit two
--fold #2E4868 Unit three, and the footer

The measured contrast pairs and their limits are in the comment at the top of assets/style.css. Text on a unit colour is full cream or full acid; keep any new unit colour dark enough that cream measures at least 4.5:1 on it.

Booking

The calendar is a front end only. At the top of assets/script.js:

  • DIARY has one entry per unit: its name, cleaning fee, photograph, a rate for each season, and booked, a list of inclusive ranges of nights ({ from: '2026-11-06', to: '2026-11-08' } is three nights; the guests leave on the 9th).
  • MONTH_SEASON says which season each month belongs to; SEASONS names them.
  • MIN_NIGHTS, CHANGEOVER_DAYS and CHANGEOVER_FROM set the minimum stay and which days longer stays must start on. MONTHS_AHEAD sets how far the diary opens.

Links like book.html?unit=the-fold&from=2026-11-20 open the calendar on that unit with a two-night stay from that date already chosen, if it is free.

The enquiry form collects the unit, arrival and leaving dates, name, email, guests, dogs and a note. It does not send anything: the submit handler in initEnquiry() shows a ready-to-send message. Point the form's action at Formspree, Netlify Forms or your own endpoint, remove the preventDefault() in initEnquiry(), and change the confirmation wording before taking real enquiries.

Accessibility and Fallbacks

  • Without JavaScript every page is complete: the hero plates are links, all three stays columns show, the day is a captioned sequence of photographs, the calendar shows a static month with taken nights struck through, and the map is a link to OpenStreetMap.
  • Under reduced motion there is no smooth scrolling or animation; the chooser, filter, slider, calendar and map keep working with instant changes.
  • The calendar is a full keyboard mirror of the drag: arrow keys move, Enter sets the first and last night, Escape clears, and a polite live region narrates the range and any taken night that stops it. On touch it is tap then tap, so page scrolling is never captured.
  • The day slider is a native range input with clickable hour marks. The photo strip is a native horizontal scroller, focusable for the keyboard.
  • The map uses cooperative gestures, so wheel and one-finger touch scroll the page.

Dependencies

  • GSAP 3.12+ with ScrollTrigger, and Flip on the stays page (the demo is built against 3.15.0)
  • Lenis 1.1+ for optional smooth scrolling (the demo is built against 1.3.17). Delete its script tag and initLenis() to go without, or add ?smooth=off to a URL to compare.
  • MapLibre GL 4.7.1 on the area page, with tiles from OpenFreeMap (OpenStreetMap data, no API key). Keep the OpenStreetMap attribution.

Images and Credits

The remaining landscape and walking photographs are from Pexels, used under the Pexels licence. The files in assets/img/ are cropped, resized and lightly desaturated WebP derivatives; assets/img-manifest.json records each source and output size. The cabin photographs (limekiln-*, peat-house-*, fold-*), the owners and farm (owners, rob-logs, farm-eggs), the night sky (night-sky) and Malham Cove (cove) are AI-generated images of buildings, people and scenes that do not exist as shown, with masters in assets/img-src/. Most photographs also ship as smaller -800w (and -1200w for the 1600px full-bleeds) files, served with srcset and a sizes attribute measured from each slot, so phones download the small files. If you replace a photograph, replace its variants too (or delete them and the srcset attribute). To regenerate after editing the manifest, run bun scripts/build-template-assets.ts holiday-let-template --force from the GSAP Vault repository, or replace a file with your own at the same name and shape.

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