013
AI ready Refreshed

Real Estate Template

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

Includes the original v1 design as a separate download.

A seven-page estate agency site built on solid colour panels set against sunlit house photographs: a draggable deck of featured homes repaints the home page, listings reshuffle and open on a real map, and every property gets a floorplan you can tour room by room. Worked example: an independent agent in Bristol.

ScrollTriggerDraggableInertiaPlugin Lenis advanced
14 more details
Flip draggablecard-stackflip-layoutfilter-chipshover-effectpage-transitioninteractive-mapform-feedbackkeyboard-manipulationscroll-revealstaggertext-animationprogressive-enhancement

Updated

About this template

A complete seven-page site for an estate agency, lettings agent or property developer, built on four committed colour panels (terracotta, harbour blue, blush and ochre) set hard against sunlit, true-colour house photography, with every home's name in an italic serif. The worked example is Marlow & Pike, an independent agent selling in six Bristol neighbourhoods.

Read the full template overview

The home page is a split: a full-bleed exterior beside a solid colour panel holding a small stack of interior photographs, with the street name set across the join. Drag the top photograph off the stack, or use the arrows, and the exterior wipes to the next house while the panel colour and the title change with it. Listings filter by area, type, price, bedrooms and saved homes, and reshuffle in place or open on a real street map with price pins; pointing across a card scrubs through its rooms. Each property page has a gallery, a floorplan where choosing a room shows its photograph, routed walking times and a viewing request card. The area guide is a real map of Bristol, recoloured to the brand, with neighbourhood pins that fly the map in and open a card of prices, stations, schools and live listings.

To make it yours, edit one array of homes in assets/homes.js, swap the photographs and repaint the four panel colours.

Real Estate Template - website template preview

What's included

10 items
  • Seven pages: home, listings, property detail, area map, area guide, selling and valuations, team and offices
  • Featured-homes deck: drag or flick the top photograph, or use the arrows and keyboard; the exterior, panel colour and street name change together
  • Listings with area, type, price, bedroom and saved-home filters that reshuffle with GSAP Flip, plus a grid/map toggle with price pins
  • Pointer scrubbing across a listing card shows its rooms; dots do the same on touch and keyboard
  • One property page for every home, driven by ?home= and a single stock array, with a static worked example for no-JS visitors
  • Interactive floorplan drawn from simple room rectangles: choose a room to see its photograph and measurements
  • Real MapLibre maps on OpenFreeMap tiles (no API key), recoloured at runtime to the brand palette
  • Area guide with a 'what your budget buys' slider, stepped valuation form with a live process timeline, draggable sold strip and flip-over team cards
  • Saved homes kept in the browser, with a count in the nav and a saved filter on listings
  • Plain multi-page navigation; the listing photograph morphs into the property hero where browsers support cross-document view transitions

Perfect for

5 use cases
  • Estate agents and real estate agencies
  • Letting agents and property management companies
  • Property developers selling the units of a scheme
  • Holiday-let and serviced-apartment portfolios
  • Architects and builders with a project index and project pages

How it works

5 sections

One stock list, seven plain pages

Each page is an ordinary HTML file sharing one stylesheet and one script. The homes, neighbourhoods and offices live in one array in assets/homes.js; the property page reads ?home= from the address and fills its hero, facts, gallery, floorplan, walking times and related homes from that array, while its static markup is a complete worked example for visitors without JavaScript.

The featured-homes deck

The home hero is a split of exterior photograph and colour panel, with the street name drawn twice and clipped to each side of the join so it reads on both. Draggable throws the top interior card off the stack; the panel colour, title letters and exterior wipe are tweened together, and the next exterior is fetched only when it is about to be needed. Buttons, arrow keys and a polite live region give the same control without dragging.

Listings and the map

Filters are native radios, selects and a checkbox. Flip records the surviving cards, the grid reflows, and the grid's height is eased so the page below does not jump. The map view builds a MapLibre map on first use with one price pin per home, and fits itself to whatever the filters leave.

Floorplans from rectangles

Each home's plan is a short list of rooms in plan units with a name, measurements and the photograph that shows it. The script draws it as SVG; photographed rooms are focusable buttons that light up and swap the photograph beside the plan.

Fallbacks

Without JavaScript every page is complete: the deck shows its first home with links to the others, filters hide and every listing shows, the valuation form appears as one form, maps become links to OpenStreetMap and team cards show both faces. Reduced motion keeps every control but swaps instantly, with no flings, wipes or flips.

Plugins ScrollTrigger, Draggable, InertiaPlugin, 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

Is this only for estate agents, or will it suit lettings and developers?

It suits any property business with a list of homes. Lettings agents change prices to monthly rents and tenure to availability dates; a developer lists the units of one scheme and turns the area map into a site plan with plots as pins. Holiday-let portfolios and architects with a project index use the same listing, detail and map pattern.

How do I add, remove or change a property?

Edit the array in assets/homes.js: street, area, price, bedrooms, features, room captions, floorplan rooms and walking times. Bake its photographs with the same naming rule, then copy one listing card in listings.html and change its data-home and text. The property page, map pins and related homes pick the new entry up automatically.

How do the floorplans work, and can I use my own drawn plans?

Each plan is a list of rectangles in plan units with a name, measurements and the index of the room photograph that shows it, and the script draws it as SVG. That keeps rooms selectable. If you already have drawn plans, put the image in place of the SVG and keep the photographed-room buttons alongside it as a list.

Do the viewing, valuation and contact forms send anything?

No. They are unwired front ends that check the fields and show a confirmation in place. The viewing card collects day, time, name and contact; the valuation form collects address, property type, bedrooms, timing, name, phone and email. Point them at your CRM (Reapit, Alto, Street), Formspree or Netlify Forms before launch.

Do the maps need an API key or account?

No. They use MapLibre GL with OpenFreeMap tiles, which are OpenStreetMap data with no key and commercial use allowed, so they work from the download as they are. The pins sit on real Bristol streets; change the coordinates in homes.js to your own patch and the maps follow. Keep the OpenStreetMap attribution.

Where do saved homes go?

They stay in the visitor's own browser (localStorage), so a shortlist survives page changes and return visits on that device without accounts. Nothing is sent to you. If you want saved searches or alerts across devices, connect the heart buttons to your CRM's buyer accounts instead.

Paid template

Purchase to unlock the code.

Buying Real Estate 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

  1. Unzip and open index.html in a browser, or serve the folder with any static server (npx serve .).
  2. The pages are plain HTML files: index.html (home), listings.html, property.html, areas.html (area map), area.html (one neighbourhood guide), sell.html and team.html.
  3. Every page shares assets/style.css, assets/homes.js and assets/script.js. There is no build step.
  4. Deploy the folder as it is to any static host.

Using It With Your Own Design

  • Colour: the palette is the token block at the top of assets/style.css. The four panel colours are --terracotta, --harbour, --blush and --ochre; each panel sets a --panel and --panel-ink pair, so keep each pair at 4.5:1 or better (the measured pairs are listed in the stylesheet's first comment).
  • Photographs: keep them true colour and in daylight. The page adapts to the photographs, never the reverse: there is no tint or overlay to match.
  • Type: Piazzolla (display, italic for every home's name) and Figtree (interface and body), self-hosted in assets/fonts/ (see Fonts below). Change the files, the @font-face rules and --font-display / --font-body.
  • Stock: one array of homes in assets/homes.js (see below).

Pages and Configuration

Page Sections Hands-on piece
Home Split hero, new this week, agency band, areas band, valuation band Featured-homes deck
Listings Title and live count, filter bar, grid or map, register band Filters, grid/map toggle, photo scrubbing
Property Split hero with facts, gallery, description, floorplan, walking times, viewing card, nearby homes Floorplan rooms, gallery, viewing request
Areas Brand-coloured map of Bristol, "Not sure where to start?" panel, six neighbourhood tiles Neighbourhood pins and cards
Area guide Split header, facts strip, editorial, budget band, homes nearby "What your budget buys" slider
Sell Split header, stepped valuation form beside the process timeline, terms, sold strip, testimonial Stepped form, draggable sold strip
Team Split header, five agent cards, two offices with a map, contact form Flip-over agent cards

Every feature looks for its own data- hook and does nothing when the markup is missing, so you can delete a section, or a page and its nav link, without editing the script.

The stock list (assets/homes.js)

window.MP.homes holds every home: slug, street, area, areaId, postcode, price, tenure, type (house or flat), kind, beds, baths, sqft, epc, tax, an optional tag (New, Under offer), at ([longitude, latitude]), summary, features, rooms (name and caption per room photograph), plan and walks.

Photographs follow one naming rule in assets/img/: <slug>-ext.webp (1400 wide) and <slug>-ext-sm.webp (640) for the front, <slug>-r1.webp, <slug>-r1-sm.webp and so on for each room, in the order of rooms.

To add a home: add an entry, bake or drop in its photographs, then copy one <article class="card"> in listings.html and change its data-home, data-area, data-type, data-price, data-beds, data-photos and text. The map pins, the area cards and the property page pick it up from the array.

window.MP.areas holds the six neighbourhoods for the area map (pin position, line, price band, station, school, link) and window.MP.offices the two offices for the team map.

Featured-homes deck (home)

Each [data-deck-card] in the hero names a home (data-deck-card="<slug>"), its panel colour and panel ink (data-panel="terracotta" data-panel-ink="cream", token names without the dashes) and carries a portrait interior (<slug>-card.webp, 560 × 720). Each [data-deck-photo] is that home's exterior; only the first loads with the page, and the next one loads when the deck is about to show it. Add or remove a home by adding or removing a card and its photo. Visitors drag or flick the top photograph, use the round arrow buttons, or focus the deck and use the arrow keys; a polite live region announces each home.

Listings

Filters are native inputs in [data-filters]: area, type, min, max, beds, saved and view. Add an area chip by adding a radio with the area's areaId as its value. listings.html?area=redland and ?saved=1 preselect a filter. Pointing across a card's photograph scrubs through the front and three rooms (from data-photos); the dots below do the same on touch and keyboard. The map view is created the first time it is opened.

Property page

property.html?home=<slug> shows any home in the array; property.html alone shows the static worked example (Hampton Road), which is also what visitors without JavaScript see. The hero, gallery, floorplan, walking times and "More homes nearby" come from the array.

The listing photograph carries view-transition-name: home-photo into the property hero, so in browsers with cross-document view transitions the photograph morphs into place. Other browsers load the page normally. Reduced motion turns the transition off.

Floorplans

plan is { w, h, floors, rooms } in plan units of any scale. Each floor is an outline { label, x, y, w, h }; each room is { name, dims, x, y, w, h, photo }, where photo is the index in rooms of the photograph that shows it, or null for a room without one. Photographed rooms are shaded, focusable buttons; choosing one lights it and swaps the photograph beside the plan.

Walking times

walks is a list of [place, metres, minutes]. The demo's figures are routed on foot along real streets with OpenStreetMap data (https://routing.openstreetmap.de/routed-foot/route/v1/foot/<lng,lat>;<lng,lat>). Recalculate them for your own homes.

Maps

All three maps are MapLibre GL on OpenFreeMap's Positron style: OpenStreetMap data, free, with no API key or account. createMap() in the script recolours the style at runtime to the brand: cream land, harbour-blue water, sage parks and white roads; change those colours there. Wheel and one-finger drag scroll the page; the map pans with Ctrl/Cmd and wheel, or two fingers on touch. Keep the OpenStreetMap attribution. Without JavaScript or WebGL each map is a link to OpenStreetMap.

MapLibre is the heaviest file on the site, so no page loads it with the page. loadMapLibre() in the script fetches its script and stylesheet when a map is about to be seen: the office map when it comes within a screen of the viewport, the listings map when the visitor reaches for the Map toggle, and the areas map at once (areas.html also preloads both files in its <head>). The two URLs are MAPLIBRE_JS and MAPLIBRE_CSS at the top of that block; change them to pin another version or self-host it. A page that includes MapLibre with its own <script> and <link> tags uses that copy instead.

Budget slider (area guide)

The examples are a JSON block ([data-budget-examples]) under the slider: price, street, area, a one-line description, image, status and an optional link. The slider shows the most expensive example at or under its value.

Forms

The register, viewing, valuation and contact forms are front ends only: they check the fields and show a confirmation in place without sending anything. Connect them to your CRM, Formspree or Netlify Forms before launch. The valuation form shows one step at a time with JavaScript and all four steps as one form without it; the home page's postcode field passes ?postcode= to it.

Saved homes

Heart buttons ([data-save="<slug>"]) keep a shortlist in the visitor's browser (localStorage, key mp-saved-homes), shown as a count on the nav button and as the Saved filter on listings. Nothing is sent anywhere.

Palette

Token Value Use
--cream #F5EDE0 Page ground; ink on it 13.8:1
--ink #2B1F1A Text and solid pills
--ink-dim #5E4E45 Secondary text, 6.8:1 on cream
--terracotta #A8482A Lead panel and tags; cream on it 5.0:1
--harbour #1D5677 Accent, links, focus ring, map water; 6.8:1 with cream either way
--blush #EDBFA8 Panel; ink on it 9.6:1 (never cream text)
--ochre #D8A23F Panel and Sold stamps; ink on it 7.0:1 (never cream text)
--sage #A9B79B Map parks only

Accessibility and Fallbacks

  • Without JavaScript, or with the GSAP CDN blocked, every page is complete: the deck shows its first home with links to the others, every listing shows, the valuation form is one form, maps are links and agent cards show both faces.
  • Reduced motion keeps every control but changes instantly: no flings, wipes, flips or reveals, and no view-transition morph.
  • Native buttons, radios, selects and a range input throughout, with visible keyboard focus. Floorplan rooms are buttons with aria-pressed; hidden card faces are inert.
  • Map pins are decorative; each map has a mirrored list of buttons or the same content as text.

Dependencies

  • GSAP 3.15.0 with ScrollTrigger, plus Draggable (home, sell), InertiaPlugin (sell) and Flip (listings) (works with 3.12+), from jsDelivr.
  • MapLibre GL 4.7.1 from unpkg on the listings, areas and team pages, loaded by the script when a map is needed (see Maps); tiles from OpenFreeMap (no key).
  • Lenis 1.3.17 for optional smooth scrolling (add ?smooth=off to a URL, or data-smooth="off" on <html>, to turn it off).
  • Piazzolla and Figtree, self-hosted in assets/fonts/.

Each page loads only the plugins it uses.

Fonts

Piazzolla (roman and italic) and Figtree are self-hosted in assets/fonts/, so no page makes a render-blocking third-party request. The files are the Latin subsets Google Fonts serves (all three are variable fonts), declared by the @font-face rules at the top of assets/style.css with the same weights and unicode-range Google uses. Each page preloads Figtree and the Piazzolla italic, the faces of the first screen. Licence: SIL Open Font License 1.1 (Piazzolla: Copyright 2018 The Piazzolla Project Authors, https://github.com/huertatipografica/piazzolla; Figtree: Copyright 2022 The Figtree Project Authors, https://github.com/erikdkennedy/figtree).

To swap a face, put your .woff2 in assets/fonts/, point its @font-face rules and the token at it, and change the preloads in each page's <head>. To use Google Fonts instead, delete the @font-face rules and the preloads and add the Google Fonts <link> to every page.

Images and Credits

Bundled photographs are WebP derivatives in assets/img/, cropped and resized but not colour graded, listed in assets/img-manifest.json. Rebuild them with bun scripts/build-template-assets.ts real-estate-template --force (in the GSAP Vault repo), or replace a file with your own at the same name and size. Each home's exterior comes in three widths, -ext (1400), -ext-md (960) and -ext-sm (640), and the browser picks one through the srcset; a replacement needs all three.

All photographs are from Pexels under the Pexels licence; every source URL is in assets/img-manifest.json (https://images.pexels.com/photos/<id>/..., page https://www.pexels.com/photo/<id>/). They include street and harbour views of Bristol (Clifton Suspension Bridge, Hotwells, Redland, the Floating Harbour, Wapping Wharf); the homes' exteriors and interiors are stock photographs paired for the example and do not show the streets they are captioned with.

Marlow & Pike, its people, offices, phone numbers, homes, prices and sales are fictional. Street names and map positions are real Bristol streets.

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