← Component Library
Advanced Components

Advanced Patterns

Higher-level building blocks — maps, location finders, calendars, scheduling, searchable FAQs, and QR codes. Each has a live demo plus the HTML, CSS, and JavaScript.

01 · Interactive Map

An embedded map you can pan and zoom

The quickest way to put a real map on a page is an <iframe> embed — no API key, no JavaScript. This one uses OpenStreetMap. Drag to pan, scroll to zoom.

HTML

<iframe
  src="https://www.openstreetmap.org/export/embed.html?bbox=-122.42,37.77,-122.40,37.79&layer=mapnik&marker=37.78,-122.41"
  width="100%" height="280" style="border:0;border-radius:10px"
  loading="lazy" title="Map"></iframe>
For full control — custom pins, popups, routes — use a JavaScript library like Leaflet (free, open-source) instead of an iframe.
02 · Google Maps Integration

Embed a specific place from Google Maps

Google Maps gives you a ready-made embed for any place. Search the location on maps.google.com, choose Share → Embed a map, and paste the iframe. The basic query embed below needs no API key.

HTML

<iframe
  src="https://maps.google.com/maps?q=Golden Gate Bridge&output=embed"
  width="100%" height="280" style="border:0;border-radius:10px"
  loading="lazy" title="Google Map"></iframe>
Maps Embed API vs. this: the official Maps Embed API (with an API key) adds directions, Street View, and styled maps. The output=embed trick shown here is simplest for just pinning one place.
03 · Location Finder

Search a list of places

A “find a location near you” list — type to filter by name or city. Try typing “portland” or “cafe”.

Bean & Code Cafe
Portland, OR
0.4 mi
Riverside Library
Portland, OR
1.2 mi
Maple Cafe
Seattle, WA
3.8 mi
Hilltop Studio
Seattle, WA
5.1 mi

HTML

<div class="finder">
  <input type="text" id="findInput" placeholder="Search locations…" aria-label="Search locations">
  <div id="findList">
    <div class="loc"><span class="pin">📍</span><div><div class="nm">Bean & Code Cafe</div><div class="ad">Portland, OR</div></div><span class="dist">0.4 mi</span></div>
    <div class="loc"><span class="pin">📍</span><div><div class="nm">Riverside Library</div><div class="ad">Portland, OR</div></div><span class="dist">1.2 mi</span></div>
    <div class="loc"><span class="pin">📍</span><div><div class="nm">Maple Cafe</div><div class="ad">Seattle, WA</div></div><span class="dist">3.8 mi</span></div>
    <div class="loc"><span class="pin">📍</span><div><div class="nm">Hilltop Studio</div><div class="ad">Seattle, WA</div></div><span class="dist">5.1 mi</span></div>
  </div>
  <p class="none" id="findNone" style="display:none;">No locations match.</p>
</div>

CSS

.finder input { width: 100%; padding: 10px 13px; border: 1px solid #cbd5e1; border-radius: 8px; font-size: .9rem; color: #111; margin-bottom: 12px; }
.loc { display: flex; align-items: center; gap: 12px; background: #fff; border: 1px solid #e5e7eb; border-radius: 10px; padding: 11px 14px; margin-bottom: 8px; }
.loc .pin { color: #14b8a6; font-size: 1.3rem; }
.loc .nm { font-weight: 700; color: #111; font-size: .9rem; }
.loc .ad { font-size: .78rem; color: #6b7280; }
.loc .dist { margin-left: auto; font-weight: 700; color: #0f766e; font-size: .82rem; }
.none { color: #6b7280; font-size: .86rem; }

JavaScript — filter the list

const input = document.getElementById('findInput');
const rows = document.querySelectorAll('#findList .loc');
const none = document.getElementById('findNone');
input.addEventListener('input', () => {
  const term = input.value.toLowerCase();
  let shown = 0;
  rows.forEach(row => {
    const match = row.textContent.toLowerCase().includes(term);
    row.style.display = match ? 'flex' : 'none';
    if (match) shown++;
  });
  none.style.display = shown ? 'none' : 'block';   // show "no match" message
});
A real finder adds geolocation: navigator.geolocation.getCurrentPosition() gets the user's coordinates so you can sort by true distance.
04 · Event Calendar

A month grid with event markers

A seven-column CSS grid makes a month view. Highlight today, and add a dot to days that have events. Click a marked day.

June 2026● has events
S
M
T
W
T
F
S
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Click a day with a dot to see its event.

HTML

<div class="cal">
  <div class="cap"><span>June 2026</span><span class="legend">● has events</span></div>
  <div class="grid">
    <div class="dow">S</div><div class="dow">M</div><div class="dow">T</div><div class="dow">W</div><div class="dow">T</div><div class="dow">F</div><div class="dow">S</div>
    <div class="day muted">31</div><div class="day">1</div><div class="day">2</div><div class="day event" data-ev="Project kickoff">3</div><div class="day">4</div><div class="day">5</div><div class="day">6</div>
    <div class="day">7</div><div class="day">8</div><div class="day today event" data-ev="Critique session">9</div><div class="day">10</div><div class="day event" data-ev="Guest lecture">11</div><div class="day">12</div><div class="day">13</div>
    <div class="day">14</div><div class="day">15</div><div class="day">16</div><div class="day">17</div><div class="day event" data-ev="Milestone due">18</div><div class="day">19</div><div class="day">20</div>
  </div>
  <p class="evt" id="evt">Click a day with a dot to see its event.</p>
</div>

CSS — the grid + markers

.cal { max-width: 360px; }
.cap { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; color: #111; font-weight: 700; }
.cap .legend { font-size: .8rem; color: #6b7280; font-weight: 600; }
.dow { text-align: center; font-size: .68rem; font-weight: 700; color: #9ca3af; padding: 4px 0; }
.grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.day  { aspect-ratio: 1; display: grid; place-items: center; border-radius: 8px;
        position: relative; background: #fff; border: 1px solid #eef2f6; color: #374151; font-size: .82rem; }
.day.muted { color: #cbd5e1; }
.day.today { background: #14b8a6; color: #fff; }
.day.event::after {            /* the event dot */
  content: ""; position: absolute; bottom: 5px;
  width: 5px; height: 5px; border-radius: 50%; background: #f59e0b;
}
.evt { margin-top: 10px; font-weight: 700; color: #0f766e; font-size: .88rem; }
05 · Appointment Scheduler

Pick an available time slot

A grid of time slots with taken ones disabled. Click an open slot to select it — the confirmation updates.

No time selected yet.

HTML

<div id="sched">
  <div class="slots">
    <button>9:00</button><button>9:30</button><button class="taken" disabled>10:00</button><button>10:30</button>
    <button>11:00</button><button class="taken" disabled>11:30</button><button>1:00</button><button>1:30</button>
  </div>
  <p class="confirm" id="confirm">No time selected yet.</p>
</div>

CSS

.slots { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px; max-width: 420px; }
.slots button { background: #fff; border: 1px solid #cbd5e1; border-radius: 8px; padding: 9px 0; font-size: .85rem; color: #374151; cursor: pointer; font-weight: 600; }
.slots button:hover { border-color: #14b8a6; }
.slots button.taken { background: #f1f5f9; color: #cbd5e1; cursor: not-allowed; text-decoration: line-through; }
.slots button.sel { background: #14b8a6; color: #fff; border-color: #14b8a6; }
.confirm { margin-top: 12px; font-weight: 700; color: #0f766e; font-size: .9rem; }

JavaScript

const confirmMsg = document.getElementById('confirm');
const slots = document.querySelectorAll('#sched .slots button');
slots.forEach(btn => {
  if (btn.disabled) return;
  btn.addEventListener('click', () => {
    slots.forEach(b => b.classList.remove('sel'));
    btn.classList.add('sel');
    confirmMsg.textContent = 'Booked for ' + btn.textContent + ' — see you then!';
  });
});
07 · QR Code Generator

Turn a link into a scannable code

QR codes are great for posters and slides. Type a URL or text and the code regenerates live. This demo uses a free QR image endpoint — in production you'd use a JavaScript library so nothing leaves the page.

QR code

HTML

<label for="qrInput">Link or text</label>
<input id="qrInput" type="text" value="https://example.com">
<img id="qrImg" alt="QR code"
     src="https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=https%3A%2F%2Fexample.com">

JavaScript — build the image URL

const input = document.getElementById('qrInput');
const img = document.getElementById('qrImg');
input.addEventListener('input', () => {
  const data = encodeURIComponent(input.value);
  img.src = 'https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=' + data;
});
Keep it offline: a library such as qrcode.js draws the QR on a <canvas> right in the browser — no third-party request, which is better for privacy.
08 · Related

Keep building

See Map Lab, Dashboard Lab, and Data Patterns — or browse the full Component Library.