137

Rooftop Cocktail Bar

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

Six-page rooftop bar and cocktail bar website template on white daylight: a ruled-table header with live sunrise and sunset, a hero you scrub from noon to 23:00 through six matched photographs of the roof, a drinks list arranged by the hour, a weather plan, a dated programme and a real map.

ScrollTrigger Lenis advanced
12 more details
scrubcrossfadescroll-revealclip-pathstaggerfiltertabsclick-togglerange-sliderview-transitionskeyboard-navigationprogressive-enhancement

Released

About this template

A six-page site for a bar where the view and the time of day are the point: a rooftop, a beach bar, a hotel terrace or a lido cafe. The page is built like a timetable on true white daylight. Every navigation item, list and table sits in a cell of hairline rules, the page is framed by two side rails with the place name set letter by letter down them, and the colour comes from the photographs and one hot accent kept for whatever is happening now. Brunswick Roof, an aperitivo and cocktail bar on the seventh-floor roof of a 1964 department store in Hove, is the worked example.

Read the full template overview

The home page opens on one full-width photograph of the roof, shot as six matched stills: noon, mid-afternoon, aperitivo, golden hour, blue hour and night. A ruled timeline across its foot runs from 12:00 to 23:00 with tonight's sunset marked. Drag it, click an hour or use the arrow keys and the photograph crossfades through the day, the side rails warm and cool with the light, and a row beneath swaps to the drinks poured at that hour, with a link that opens the full list at the same point. It starts at the bar's real local time, and the sunrise and sunset in the header are calculated for the bar's own latitude and longitude.

Inside, Drinks arranges the list by the hour as a numbered edition with low and no-alcohol filters; The Roof sets the terrace and the glasshouse side by side and has a weather plan you can switch between sun, wind and rain; What's On turns weekly and monthly rules into the next six weeks of dated rows, each with its sunset; Private Hire works out which space fits a headcount and prices the packages; Visit has hours tables with last orders, house rules, a real street map with routed walks and a table booking form.

Making it yours is mostly photographs, copy and one configuration block: the place, time zone, season and opening hours sit at the top of the script, colours are a handful of tokens, and drinks, events and spaces are plain HTML with data attributes.

Rooftop Cocktail Bar - website template preview

What's included

10 items
  • Day scrubber hero: six matched photographs of one view crossfaded from noon to 23:00 on a ruled timeline, by drag, click, arrow keys or touch
  • Sunset marked on the timeline and the drinks for the scrubbed hour shown beneath, linking to the full list at that hour
  • Live sunrise and sunset in the header, calculated for the bar's coordinates, and an open-now line that knows the season
  • Ruled-table header of bordered link cells, framed page edges with the place name down the side rails
  • Drinks list arranged by the hour as a numbered edition, with low and no-alcohol filters and the current hour marked
  • Weather plan for sun, wind and rain that swaps the seating plan and photograph
  • Programme built from weekly and monthly rules into the next six weeks of dated rows, each with that evening's sunset, filterable by series
  • Private hire calculator: space and headcount give a fit verdict and package totals
  • Hours tables with last orders and today's row marked, house rules, and a real street map (MapLibre on OpenFreeMap) with two routed walks
  • Phone menu as a full-width ruled sheet; six plain HTML pages with a cross-document view transition, complete without JavaScript

Perfect for

5 use cases
  • Rooftop bars, sky bars and terrace bars
  • Beach bars, beach clubs and seafront cafes
  • Hotel terraces, pool bars and lido cafes
  • Garden bars, beer gardens and seasonal pop-ups
  • Learning pattern: a native range input driving an opacity-only crossfade, copy and a linked page state

How it works

5 sections

The day on the roof

The hero stacks six photographs of the same view. A native range input from 12:00 to 23:00 lies invisibly over a ruled timeline, so the control is a real slider for keyboard, touch and screen readers. As its value moves, the five later photographs fade in over the noon one by opacity alone, each keyed to tonight's sunset, and the side rails pick up a faint colour temperature. The row of drinks below switches to the part of the day the time falls in. Under reduced motion every change is instant; without JavaScript the noon photograph and all four drinks rows show.

Sun times and the open-now line

One configuration object holds the bar's latitude, longitude, time zone, season and opening hours. Sunrise and sunset come from the standard solar formulae, so there is no weather or astronomy API to sign up for. The header, the scrubber's sunset mark, today's row in the hours tables and the What's On sunset column all read from it, and the open-now line says when the bar is closed for the winter.

Drinks by the hour

Each part of the day is a section of plain list items with a number, name, specification, strength and price. A data attribute marks the low and no-alcohol drinks for the filter buttons, and the index column follows the scroll. Arriving from the home page with a time opens the list at that hour and labels it.

Programme from rules

What's On lists each series once, with a weekly or first-of-the-month rule and a start time that can be fixed or set relative to sunset. The script turns those into the next six weeks of open days, skips the closed season with a single row saying so, rotates the performers' names and adds that evening's sunset. Without JavaScript the series rows read as an ordinary list.

Navigation, map and fallbacks

Pages are ordinary links with a CSS cross-document view transition. On phones the ruled header folds into a Menu button that opens a full-width ruled sheet with focus handling and Escape to close; without JavaScript the same links show in the page. The Visit map loads MapLibre only when it nears the viewport, uses cooperative gestures so it never traps the scroll, and keeps an OpenStreetMap link if it cannot load. Forms are static front ends that say nothing was sent.

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 (6 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 kinds of business does this rooftop bar template suit?

Any bar or cafe where the view and the light are the draw: a rooftop or sky bar, a beach bar or beach club, a hotel terrace or pool bar, a lido cafe, a garden bar or beer garden. The timeline, the drinks-by-hour list and the weather plan carry over directly; rename the spaces, replace the six hero photographs and set your own coordinates and season.

How do I replace the six hero photographs with my own?

You need six photographs of the same view from the same spot, ideally on a tripod: midday, mid-afternoon, early evening, golden hour, blue hour and after dark. Save them over roof-noon, roof-afternoon, roof-aperitivo, roof-golden, roof-blue and roof-night in assets/img, with the 800 and 1200 pixel copies, at 16:9. The crossfade only lines up if the framing matches.

Do the private hire and glasshouse booking forms send anything?

No. Both are static front ends with no backend. The hire form collects a name, email, date, guest count, space, package and notes; the table form collects a date, time, party size, name and email. On submit they say plainly that nothing was sent. Point them at Formspree, Netlify Forms, your booking system or your CRM.

How are the sunset times worked out, and can I move the bar?

They are calculated in the browser from a latitude and longitude at the top of assets/script.js, with no API or key. Change those two numbers and the time zone, and the header, the scrubber's sunset mark and the What's On sunset column all follow. The same block sets your season dates and opening hours.

How do I change the drinks list and which drinks show on the home page?

The full list on drinks.html is plain HTML: each drink is a list item with its number, name, specification, strength and price, inside a section for its part of the day. Mark low or no-alcohol drinks with data-kind so the filters find them. The home page row holds three picks per part of the day in its own small block; edit those to match.

How do I set up my own events on the What's On page?

Write each series once as a row with a rule such as weekly:4 for Thursdays or monthly-first:3 for the first Wednesday, a start and end time (or sunset-60 for an hour before sunset) and a list of names to rotate. The page builds the next six weeks of dates from those rows and skips your closed season. One-off events can be added as extra rows.

Paid template

Purchase to unlock the code.

Buying Rooftop Cocktail Bar 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 upload the folder to any static host. There is no build step.
  2. The six pages are index.html, drinks.html, roof.html, whats-on.html, private-hire.html and visit.html. Each loads assets/style.css and assets/script.js and works on its own.
  3. Set the bar's place, time zone, season and hours in the ROOF object at the top of assets/script.js.
  4. Edit the copy in the HTML and the colour tokens at the top of assets/style.css.
  5. Replace the photographs in assets/img/ with your own at the same file names and similar proportions (see Images and Credits).

Using It With Your Own Design

Every interactive part is found by a data- hook (data-day, data-pour, data-menu-list, data-plan, data-events, data-event-filter, data-hire, data-form, data-hours, data-routes) and its initialiser returns early when the hook is missing, so you can delete any section and the rest keeps working. To lift one part into another site, copy its markup, the matching block of assets/style.css (each is headed by a comment) and its init function from assets/script.js.

The frame (awning stripe, side rails, ruled header and footer) is ordinary markup repeated on each page. Navigation between pages is plain links with a CSS cross-document view transition (@view-transition { navigation: auto; }), so there is no router to configure. Change a page name in the header cells, the phone sheet (the same list) and the footer.

Configuration

At the top of assets/script.js:

  • ROOF.lat, ROOF.lng: the bar's position, used to calculate sunrise and sunset in the browser. No API or key.
  • ROOF.timeZone: the bar's clock (an IANA name such as Europe/London). "Now", the open-now line and the sun times use it, so a visitor abroad sees the bar's local time.
  • ROOF.season: first and last open day as [month, day]. Outside it the header says the bar is closed for the winter and the What's On dates jump to the next season.
  • ROOF.open, ROOF.close: opening and closing time in minutes after midnight.

The date pin. Every page ships with data-today="2026-07-16" on <html>, so the demo always shows an open bar in midsummer. The open-now line, today's rows in the hours tables, the sunrise and sunset times, the What's On dates and the scrubber's sunset all read that date; the time of day (where the scrubber opens, whether the bar is open now) is always the real clock. For a live site, set data-today="auto" (or remove the attribute) on every page so everything follows the real date.

Pages

Home (index.html)

The day on the roof (data-day). Six <img> elements share one frame: the noon still is in the markup with src, srcset and fetchpriority="high"; the other five (data-still="afternoon", "aperitivo", "golden", "blue", "night", in that order) carry the full data-src path of their largest file and are loaded after the page has painted, with the -800 and -1200 copies added to their srcset. A native <input type="range"> from 720 (12:00) to 1380 (23:00) in steps of ten minutes lies invisibly over the ruled timeline; it is the control for mouse, touch, keyboard and screen readers. Every change is keyed to tonight's sunset, so the photograph follows the season: golden hour peaks about 40 minutes before sunset, blue hour and night follow it, and the afternoon and aperitivo stills split the time from opening to golden hour (on a July evening, afternoon from about 14:00 and aperitivo from about 17:00). The stack order is LAYERS, the rail colours STILL_TINT and the stamp text STAMPS in initDay.

To pin the opening time (for a screenshot, say), add data-time="17:30" to the [data-day] section; otherwise it opens at the bar's current time, clamped to opening hours.

Pouring at (data-pour). One .pour__set per part of the day, each with data-period (the id of the matching section on drinks.html) and data-from / data-to in minutes. Edit the three drinks in each. "See the full list" follows the scrubbed time to drinks.html?at=17:30#aperitivo.

What's On teaser (data-events data-limit="4") uses the same event rows as the What's On page; see below.

Drinks (drinks.html)

Each part of the day is a <section class="hour" data-hour data-from data-to> with an ordered list of .drink items: number, name, strength, price and specification. Set data-kind="low" or data-kind="none" on a drink for the Low ABV and No ABV filters, and add the small flag in its strength cell. The index column is built from the section ids. The current part of the day (or the one passed as ?at=) is labelled.

The Roof (roof.html)

The two spaces are plain articles with a specification list. The weather plan (data-plan) is three radio inputs (value="sun", "wind", "rain"), a photograph per state (data-plan-photo) and a panel per state (data-plan-panel). Add a state by adding all three with the same value.

What's On (whats-on.html)

Each series is written once as a list item:

Code snippet omitted: it ships with the download.

  • data-rule: weekly:<day>, monthly-first:<day> or monthly-last:<day>, with the day as 0 to 6, Sunday first.
  • data-start, data-end: HH:MM, or sunset plus or minus minutes.
  • data-names: names to rotate week by week, separated by |.
  • data-event: the series key, matched by the filter buttons' data-filter.

The script replaces these rows with the next six weeks of open days (data-weeks on the list), adds each evening's sunset and inserts a single row for the closed season. Without JavaScript the series rows read as an ordinary list.

Private Hire (private-hire.html)

Spaces are radios with data-cap and data-min; the guest range runs from 30 to 180. The fit messages are in initHire. Package totals multiply the head price in each .pack's data-pack by the guest count. The enquiry form's guests and space follow the controls above it.

Visit (visit.html)

Each hours tile is a small table; rows with data-days="0-6" (or 1-6, or 0 for Sunday) are marked as today in the accent. The map section carries data-pin (longitude, latitude) and the walking routes are ROUTES in the script, as [lng, lat] arrays from the public OSRM foot router:

Code snippet omitted: it ships with the download.

Keep the minutes and distances in the route buttons in step with the router's result, and the station positions in STATIONS.

Forms

The private hire enquiry and the glasshouse table form are static front ends with no backend. On submit they say that nothing was sent. Connect them to Formspree, Netlify Forms, your booking system or your CRM by giving the <form> an action and removing initForms (or replacing its submit handler with your own request).

Palette

Token Value Use
--ground #FFFFFF Page ground
--ink #14141A Text and every rule
--ink-dim #5C5F66 Secondary text (6.40:1 on white)
--now #E0124F "Now" only: today's hours, sunset, the scrubbed time, what's pouring (4.81:1 on white)
--cobalt #1E3FC0 The awning stripe and pressed filter buttons
--pool #E3EDF8 The weather plan panel
--tint written by the script The rails' colour temperature for the scrubbed hour

Measured pairs and limits are recorded in the :root comment of assets/style.css. Keep --now for live information; used for decoration it stops meaning anything.

Fonts: Encode Sans (one variable file: capitals at 125% width for names and labels, headings at 115%, body at 100%) and Fragment Mono for every figure.

Accessibility and Fallbacks

  • The day scrubber is a native range input: arrow keys, Page Up and Down, Home and End all work, and it announces the time, the light and what is pouring.
  • Filters and route buttons use aria-pressed; the weather plan and hire spaces are radio groups.
  • The phone menu is a real button with aria-expanded and aria-controls; focus moves into the sheet and returns on Escape; the current page is marked with aria-current.
  • Focus rings show for keyboard use only (:focus-visible).
  • Reduced motion: no smooth scroll, no reveals, no view transition; the scrubber swaps stills instantly.
  • Without JavaScript: the noon photograph and all four drinks rows show, the navigation sheet is an ordinary list of links, the weather plan shows all three plans, the programme shows its series, and the map is a link to OpenStreetMap.
  • If the GSAP CDN is blocked, the page drops its reveal gate and reads as a plain document, with the sun times still filled in.

Dependencies

  • GSAP 3.15.0 with ScrollTrigger (works with 3.12+).
  • Lenis 1.3.17 for smooth scrolling (optional; add ?smooth=off or data-smooth="off" on <html> to switch it off). The phone menu sheet stops it while open.
  • MapLibre GL 4.7.1 with OpenFreeMap tiles on the Visit page (no API key; keep the OpenStreetMap attribution). It loads only when the map nears the viewport; the URLs are MAPLIBRE_JS and MAPLIBRE_CSS in assets/script.js.
  • Encode Sans and Fragment Mono, self-hosted in assets/fonts/.

Fonts

Both families are self-hosted Latin subsets in assets/fonts/, declared by the @font-face rules at the top of assets/style.css, so no page makes a render-blocking third-party request. Encode Sans is one variable file covering weights 100 to 900 and widths 75% to 125%; each page preloads it. Licence: SIL Open Font License 1.1, full text in assets/fonts/OFL.txt (Encode Sans: Copyright 2016 The Encode Sans Project Authors; Fragment Mono: Copyright 2022 The Fragment Mono Project Authors).

To swap a face, put your .woff2 in assets/fonts/, point its @font-face rule and the --font-* token at it, and change the preload in each page's <head>.

Images and Credits

Photographs are bundled as graded, resized WebP derivatives in assets/img/. assets/img-manifest.json lists each output, its source and grade; re-bake with bun scripts/build-template-assets.ts rooftop-bar-template --force from the GSAP Vault repository, or replace a file in assets/img/ with your own at the same name.

Generated images. The six hero stills (roof-noon, roof-afternoon, roof-aperitivo, roof-golden, roof-blue, roof-night, each with -1200 and -800 copies) are AI-generated images (Codex image model, October 2026) of a fictional rooftop terrace; the JPEG masters are in assets/img-src/. They depict no real bar, building or person. Replace them with six photographs of your own view taken from one spot through a day.

The other scene photographs are AI-generated the same way, of the same fictional roof and its building: drink-aperitivo, drink-afterdark, glasshouse-plants, terrace-rail, terrace-blue, terrace-white, band, dj, hire-party, hire-table, toast, building and lift-lobby. Their masters are in assets/img-src/ too. They show no real venue, staff or guests; swap them for photographs of your own place before launch.

Stock photographs, from Pexels under the Pexels licence:

File Source
drink-noon https://www.pexels.com/photo/36786940/
drink-sundown https://www.pexels.com/photo/30427296/
line-up https://www.pexels.com/photo/33013700/
plates https://www.pexels.com/photo/5914365/
glasshouse https://www.pexels.com/photo/5367412/
parasol-sky https://www.pexels.com/photo/1154985/
spritz-terrace https://www.pexels.com/photo/6761500/
coast https://www.pexels.com/photo/17938478/

Map data © OpenStreetMap contributors, tiles by OpenFreeMap.

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