Free
Footer
Tressa Footer
A footer block extracted from the Tressa template, available in Tailwind CSS and Bootstrap.
0
3
A footer block extracted from the Tressa template, available in Tailwind CSS and Bootstrap.
<!DOCTYPE html>
<html lang="en">
<head>
<script>
window.FontAwesomeConfig = { autoReplaceSvg: 'nest' };
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/js/all.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tressa Footer | Tailwind CSS UI Block</title>
<meta name="description" content="A footer block extracted from the Tressa template, available in Tailwind CSS and Bootstrap.">
<meta name="keywords" content="Tressa, Tailwind CSS template, HTML website template, hair salon template, hair studio, hairdresser website, balayage, keratin treatment, salon booking">
<meta name="author" content="Let's templates">
<link rel="canonical" href="">
<meta property="og:type" content="product">
<meta property="og:site_name" content="Let's templates">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="">
<meta property="og:title" content="Tressa | Tailwind CSS Health & Fitness Template">
<meta property="og:description" content="A clean, minimal Tailwind CSS hair salon template with numbered services, a work gallery, stylist profiles and service packages.">
<meta property="og:image" content="">
<meta property="og:image:alt" content="Tressa template preview">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:url" content="">
<meta name="twitter:title" content="Tressa | Tailwind CSS Health & Fitness Template">
<meta name="twitter:description" content="A clean, minimal Tailwind CSS hair salon template with numbered services, a work gallery, stylist profiles and service packages.">
<meta name="twitter:image" content="">
<meta name="twitter:image:alt" content="Tressa template preview">
<script src="https://cdn.tailwindcss.com/3.4.17"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: { ink: '#111827', mist: '#f8f9fb', line: '#e5e7eb' },
fontFamily: { sans: ['Inter', 'sans-serif'] }
}
}
}
</script>
<style>
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: 180ms ease-out both page-fade-out; }
::view-transition-new(root) { animation: 220ms ease-in both page-fade-in; }
@keyframes page-fade-out { to { opacity: 0; } }
@keyframes page-fade-in { from { opacity: 0; } }
html { scroll-behavior: smooth; }
.reveal-ready [data-reveal] { opacity: 0; transform: translateY(24px); transition: opacity .6s ease, transform .6s ease; transition-delay: var(--reveal-delay, 0ms); }
.reveal-ready [data-reveal].is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}
</style>
</head>
<body class="bg-white font-sans text-ink antialiased">
<% active_page = "index" %>
<% { "services" => "Services", "work" => "Work", "team" => "Team", "contact" => "Contact" }.each do |slug, label| %>
<% active = active_page == slug %>
<% end %>
<% { "index" => "Home", "services" => "Services", "work" => "Work", "team" => "Team", "pricing" => "Pricing", "contact" => "Contact" }.each do |slug, label| %>
<% active = active_page == slug %>
<% end %>
<% [["12", "+", "Years"], ["6", "K+", "Guests"], ["4.9", "", "Rating"]].each do |value, suffix, label| %>
<% end %>
<% [
["Haircut", "Precise cuts shaped around your face and hair type.", "From $80", "services.html"],
["Colour", "Natural colour, glosses and hand-painted balayage.", "From $140", "balayage.html"],
["Styling", "Blow-dries and occasion styles that hold all day.", "From $60", "services.html"],
["Treatment", "Keratin smoothing and deep repair for tired hair.", "From $90", "keratin-treatment.html"]
].each_with_index do |(title, copy, price, href), index| %>
<% end %>
<% [["1582095133179-bfd08e2fc6b3", "Stylist pinning soft curls into an elegant updo"], ["1633681926022-84c23e8cb2d6", "Bright modern salon with round mirrors and styling chairs"], ["1562322140-8baeececf3df", "Stylist blow-drying a guest's shoulder-length hair"], ["1492106087820-71f1a00d2b11", "Long wavy lavender-toned hair"]].each_with_index do |(image, alt), index| %>
<% end %>
<% [["Clara Moreau", "Creative Director", "1582095133179-bfd08e2fc6b3", "Updo in progress by Clara"], ["Owen Hart", "Colour Specialist", "1554519515-242161756769", "Vivid multi-tone colour by Owen"], ["Mei Tanaka", "Senior Stylist", "1595476108010-b4d1f102b1b1", "Mei washing a guest's hair before a cut"]].each_with_index do |(name, role, image, alt), index| %>
<% end %>
<% [["Salon-grade products", "Gentle, professional formulas chosen for each hair type."], ["Always learning", "Our team trains every season in new cuts and colour."], ["Made for you", "A real consultation before every service, never a script."], ["A calm space", "Natural light, quiet music and no rushing between guests."]].each_with_index do |(title, copy), index| %>
<% end %>
<% [
["Essential", "$189", ["Haircut", "Repair treatment", "Simple styling", "Consultation"], false],
["Signature", "$379", ["Haircut", "Colour service", "Repair treatment", "Finish styling", "Take-home kit"], true],
["Complete", "$569", ["Haircut", "Full colour", "Keratin smoothing", "Event styling", "Take-home kit", "Priority booking"], false]
].each_with_index do |(name, price, items, featured), index| %>
<% if featured %>
<% end %>
<% items.each do |item| %>
<% end %>
<% end %>
<% [
["Clara gave me the cut I've been describing to stylists for years. I finally feel like myself again.", "Hannah Brooks"],
["Fair prices and real listening. They talked me out of a colour that would have washed me out.", "Daniel Reyes"],
["Bright, calm and spotless. My balayage grew out beautifully and still looks soft months later.", "Priya Sharma"],
["I book every visit now. The whole team is kind, skilled and never rushes you out of the chair.", "Ethan Walsh"]
].each_with_index do |(quote, name), index| %>
<% 5.times do %>
<% end %>
<% end %>
<% [["1522337360788-8b13dee7a37e", "Long glossy waves seen from behind"], ["1582095133179-bfd08e2fc6b3", "Soft updo pinned in place"], ["1554519515-242161756769", "Vivid rainbow colour"], ["1562322140-8baeececf3df", "Smooth blow-dry finish"], ["1492106087820-71f1a00d2b11", "Lavender-toned waves"], ["1559599101-f09722fb4948", "Three smiling stylists with their tools"], ["1634449571010-02389ed0f9b0", "Relaxing hair wash at the basin"], ["1595476108010-b4d1f102b1b1", "Stylist laughing with a guest during a wash"]].each_with_index do |(image, alt), index| %>
<% end %>
<!-- block:start footer -->
<footer class="border-t border-line bg-mist">
<div class="mx-auto grid max-w-6xl gap-10 px-5 py-16 md:grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,1fr)] md:px-8">
<div>
<a href="index.html" class="text-2xl font-medium tracking-tight">Tressa Studio</a>
<p class="mt-5 max-w-sm leading-relaxed text-ink/70">A calm hair studio for precise cuts, natural colour and treatments that keep hair healthy.</p>
<ul class="mt-6 flex gap-3">
<li><a href="https://instagram.com" aria-label="Instagram" class="grid h-11 w-11 place-items-center border border-line bg-white hover:border-ink"><i class="fa-brands fa-instagram" aria-hidden="true"></i></a></li>
<li><a href="https://facebook.com" aria-label="Facebook" class="grid h-11 w-11 place-items-center border border-line bg-white hover:border-ink"><i class="fa-brands fa-facebook-f" aria-hidden="true"></i></a></li>
</ul>
</div>
<div>
<h2 class="text-sm font-medium uppercase tracking-[0.15em]">Links</h2>
<ul class="mt-5 space-y-3 text-ink/70">
<% { "services" => "Services", "work" => "Work", "team" => "Team", "pricing" => "Pricing", "contact" => "Contact" }.each do |slug, label| %>
<li><a href="<%= slug %>.html" class="hover:text-ink"><%= label %></a></li>
<% end %>
</ul>
</div>
<div>
<h2 class="text-sm font-medium uppercase tracking-[0.15em]">Contact</h2>
<ul class="mt-5 space-y-3 text-ink/70">
<li class="flex gap-3"><i class="fa-solid fa-location-dot mt-1" aria-hidden="true"></i><address class="not-italic">905 W Fulton St<br>Chicago, IL 60607</address></li>
<li class="flex gap-3"><i class="fa-solid fa-phone mt-1" aria-hidden="true"></i><a href="tel:+13125550194" class="hover:text-ink">(312) 555-0194</a></li>
<li class="flex gap-3"><i class="fa-regular fa-clock mt-1" aria-hidden="true"></i>Tue–Sat · 9:00–19:00</li>
</ul>
</div>
</div>
<div class="mx-auto flex max-w-6xl flex-col gap-3 border-t border-line px-5 py-6 text-sm text-ink/60 md:flex-row md:items-center md:justify-between md:px-8">
<p>© <span data-current-year>2026</span> Tressa Studio. All rights reserved.</p>
<a href="contact.html" class="hover:text-ink">Privacy & terms</a>
</div>
</footer>
<!-- block:end footer -->
<script>
document.querySelectorAll('[data-menu-toggle]').forEach((button) => {
const menu = document.getElementById(button.getAttribute('aria-controls'));
if (!menu) return;
button.addEventListener('click', () => {
const open = button.getAttribute('aria-expanded') === 'true';
button.setAttribute('aria-expanded', String(!open));
menu.classList.toggle('hidden', open);
});
});
document.querySelectorAll('[data-filter-group]').forEach((group) => {
const buttons = group.querySelectorAll('[data-filter]');
buttons.forEach((button) => {
button.addEventListener('click', () => {
buttons.forEach((other) => {
const active = other === button;
other.setAttribute('aria-pressed', String(active));
other.classList.toggle('bg-ink', active);
other.classList.toggle('text-white', active);
});
document.querySelectorAll('[data-filter-item]').forEach((item) => {
item.hidden = button.dataset.filter !== 'all' && item.dataset.category !== button.dataset.filter;
});
});
});
});
document.querySelectorAll('[data-accordion]').forEach((accordion) => {
const triggers = accordion.querySelectorAll('[data-accordion-trigger]');
triggers.forEach((trigger) => {
trigger.addEventListener('click', () => {
const willOpen = trigger.getAttribute('aria-expanded') !== 'true';
triggers.forEach((other) => {
const open = other === trigger && willOpen;
other.setAttribute('aria-expanded', String(open));
document.getElementById(other.getAttribute('aria-controls')).classList.toggle('hidden', !open);
other.querySelector('[data-accordion-icon]')?.classList.toggle('rotate-45', open);
});
});
});
});
document.querySelectorAll('[data-contact-form]').forEach((form) => {
form.addEventListener('submit', (event) => {
event.preventDefault();
const status = form.querySelector('[data-form-status]');
if (!form.checkValidity()) {
status.textContent = form.dataset.error || 'Please complete the required fields.';
return;
}
status.textContent = form.dataset.success || 'Thanks! We will be in touch soon.';
form.reset();
});
});
document.querySelectorAll('[data-current-year]').forEach((el) => { el.textContent = new Date().getFullYear(); });
(() => {
const counters = document.querySelectorAll('[data-count-to]');
if (!counters.length || navigator.webdriver || matchMedia('(prefers-reduced-motion: reduce)').matches || !('IntersectionObserver' in window)) return;
const observer = new IntersectionObserver((entries) => {
entries.forEach(({ isIntersecting, target }) => {
if (!isIntersecting) return;
observer.unobserve(target);
const end = Number(target.dataset.countTo);
const suffix = target.dataset.countSuffix || '';
const start = performance.now();
const tick = (now) => {
const progress = Math.min((now - start) / 700, 1);
target.textContent = Math.round(end * progress) + suffix;
if (progress < 1) requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
});
}, { threshold: 0.6 });
counters.forEach((counter) => observer.observe(counter));
})();
(() => {
const items = document.querySelectorAll('[data-reveal]');
const skip = navigator.webdriver || !('IntersectionObserver' in window) || matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!items.length || skip) return;
document.documentElement.classList.add('reveal-ready');
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
entry.target.classList.add('is-visible');
observer.unobserve(entry.target);
});
}, { rootMargin: '0px 0px -10% 0px' });
items.forEach((item) => observer.observe(item));
})();
</script>
</body>
</html>
Business
Unlock the entire library of premium templates and blocks. Renews automatically, cancel anytime.