UI Components Easy
Footer Links
Multi-column site footer with logo, link groups, newsletter subscribe input, social icons, and legal row. Pure CSS responsive layout.
Open in Lab
MCP
css vanilla-js
Targets: JS HTML
Code
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg: #0f1117;
--footer-bg: #0a0c12;
--surface: #16181f;
--border: #1e2130;
--text: #e2e8f0;
--text-muted: #64748b;
--text-dim: #475569;
--accent: #818cf8;
--accent-hover: #a5b4fc;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
background: var(--bg);
color: var(--text);
display: flex;
flex-direction: column;
min-height: 100vh;
}
.page-body {
flex: 1;
display: grid;
place-items: center;
}
.placeholder {
text-align: center;
color: var(--text-muted);
}
.placeholder-icon {
font-size: 2rem;
margin-bottom: 8px;
color: var(--accent);
}
.placeholder p {
font-size: 0.875rem;
}
/* ── Footer ── */
.footer {
background: var(--footer-bg);
border-top: 1px solid var(--border);
}
.footer-inner {
max-width: 1200px;
margin: 0 auto;
padding: 56px 32px 40px;
display: grid;
grid-template-columns: 260px 1fr;
gap: 48px;
}
/* Brand */
.footer-logo {
display: inline-flex;
align-items: center;
gap: 8px;
text-decoration: none;
font-size: 1.1rem;
font-weight: 700;
color: var(--text);
margin-bottom: 14px;
}
.footer-logo-icon {
color: var(--accent);
}
.footer-logo:hover {
color: var(--accent);
}
.footer-tagline {
font-size: 0.82rem;
color: var(--text-muted);
line-height: 1.7;
margin-bottom: 20px;
}
/* Social */
.footer-social {
display: flex;
gap: 8px;
}
.social-link {
width: 34px;
height: 34px;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--surface);
color: var(--text-muted);
display: grid;
place-items: center;
text-decoration: none;
transition: color .15s, border-color .15s, background .15s;
}
.social-link:hover {
color: var(--text);
border-color: var(--accent);
background: rgba(129, 140, 248, 0.08);
}
/* Link groups */
.footer-links-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 24px;
}
.footer-group {
display: flex;
flex-direction: column;
gap: 10px;
}
.footer-group-title {
font-size: 0.78rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .08em;
color: var(--text);
margin-bottom: 4px;
}
.footer-link {
font-size: 0.85rem;
color: var(--text-muted);
text-decoration: none;
transition: color .15s;
width: fit-content;
}
.footer-link:hover {
color: var(--text);
}
/* Newsletter */
.footer-newsletter-desc {
font-size: 0.8rem;
color: var(--text-muted);
line-height: 1.5;
margin-bottom: 4px;
}
.footer-newsletter-form {
display: flex;
flex-direction: column;
gap: 6px;
}
.newsletter-input {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 7px;
color: var(--text);
font-size: 0.82rem;
padding: 8px 12px;
outline: none;
font-family: inherit;
transition: border-color .15s;
}
.newsletter-input::placeholder {
color: var(--text-dim);
}
.newsletter-input:focus {
border-color: var(--accent);
}
.newsletter-btn {
background: var(--accent);
border: none;
border-radius: 7px;
color: #fff;
font-size: 0.82rem;
font-weight: 600;
padding: 8px 14px;
cursor: pointer;
transition: background .15s, opacity .15s;
font-family: inherit;
}
.newsletter-btn:hover {
background: var(--accent-hover);
}
.newsletter-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.newsletter-msg {
font-size: 0.8rem;
color: #34d399;
margin-top: 4px;
}
.newsletter-msg.error {
color: #f87171;
}
/* Legal row */
.footer-legal {
max-width: 1200px;
margin: 0 auto;
padding: 16px 32px;
border-top: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
font-size: 0.78rem;
color: var(--text-dim);
gap: 16px;
flex-wrap: wrap;
}
.legal-links {
display: flex;
gap: 16px;
}
.legal-link {
color: var(--text-dim);
text-decoration: none;
transition: color .15s;
}
.legal-link:hover {
color: var(--text-muted);
}
/* ── Responsive ── */
@media (max-width: 900px) {
.footer-inner {
grid-template-columns: 1fr;
gap: 32px;
}
.footer-links-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 500px) {
.footer-links-grid {
grid-template-columns: 1fr;
}
.footer-inner {
padding: 32px 20px 24px;
}
.footer-legal {
padding: 12px 20px;
font-size: 0.72rem;
}
}const form = document.getElementById("newsletterForm");
const input = document.getElementById("newsletterEmail");
const btn = form?.querySelector(".newsletter-btn");
const msg = document.getElementById("newsletterMsg");
function isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim());
}
form?.addEventListener("submit", async (e) => {
e.preventDefault();
const email = input.value;
if (!isValidEmail(email)) {
showMsg("Please enter a valid email address.", true);
input.focus();
return;
}
btn.disabled = true;
btn.textContent = "Subscribing…";
// Simulate API call
await new Promise((r) => setTimeout(r, 1000));
showMsg("✓ You're subscribed! Check your inbox.", false);
input.value = "";
btn.textContent = "Subscribe";
btn.disabled = false;
// Reset message after 4 s
setTimeout(() => {
msg.hidden = true;
}, 4000);
});
function showMsg(text, isError) {
msg.textContent = text;
msg.className = "newsletter-msg" + (isError ? " error" : "");
msg.hidden = false;
}<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Footer Links</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- Page content placeholder -->
<main class="page-body">
<div class="placeholder">
<div class="placeholder-icon">✦</div>
<p>Page content above the footer</p>
</div>
</main>
<!-- ── Footer ── -->
<footer class="footer">
<div class="footer-inner">
<!-- Brand -->
<div class="footer-brand">
<a href="#" class="footer-logo">
<span class="footer-logo-icon">✦</span> StealThis
</a>
<p class="footer-tagline">
Ready-to-use snippets, demos, and patterns.<br />All free to copy.
</p>
<!-- Social icons -->
<div class="footer-social">
<a href="#" class="social-link" aria-label="GitHub">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
<path
d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0 1 12 6.844a9.59 9.59 0 0 1 2.504.337c1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.02 10.02 0 0 0 22 12.017C22 6.484 17.522 2 12 2z" />
</svg>
</a>
<a href="#" class="social-link" aria-label="Twitter / X">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
<path
d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
</svg>
</a>
<a href="#" class="social-link" aria-label="Discord">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
<path
d="M20.317 4.492c-1.53-.69-3.17-1.2-4.885-1.49a.075.075 0 0 0-.079.036c-.21.369-.444.85-.608 1.23a18.566 18.566 0 0 0-5.487 0 12.36 12.36 0 0 0-.617-1.23A.077.077 0 0 0 8.562 3c-1.714.29-3.354.8-4.885 1.491a.07.07 0 0 0-.032.027C.533 9.093-.32 13.555.099 17.961a.08.08 0 0 0 .031.055 20.03 20.03 0 0 0 5.993 2.98.078.078 0 0 0 .084-.026 13.83 13.83 0 0 0 1.226-1.963.074.074 0 0 0-.041-.104 13.175 13.175 0 0 1-1.872-.878.075.075 0 0 1-.008-.125c.126-.093.252-.19.372-.287a.075.075 0 0 1 .078-.01c3.927 1.764 8.18 1.764 12.061 0a.075.075 0 0 1 .079.009c.12.098.245.195.372.288a.075.075 0 0 1-.006.125c-.598.344-1.22.635-1.873.877a.075.075 0 0 0-.041.105c.36.687.772 1.341 1.225 1.962a.077.077 0 0 0 .084.028 19.963 19.963 0 0 0 6.002-2.981.076.076 0 0 0 .032-.054c.5-5.094-.838-9.52-3.549-13.442a.06.06 0 0 0-.031-.028zM8.02 15.278c-1.182 0-2.157-1.069-2.157-2.38 0-1.312.956-2.38 2.157-2.38 1.21 0 2.176 1.077 2.157 2.38 0 1.312-.956 2.38-2.157 2.38zm7.975 0c-1.183 0-2.157-1.069-2.157-2.38 0-1.312.955-2.38 2.157-2.38 1.21 0 2.176 1.077 2.157 2.38 0 1.312-.946 2.38-2.157 2.38z" />
</svg>
</a>
<a href="#" class="social-link" aria-label="LinkedIn">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
<path
d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" />
</svg>
</a>
</div>
</div>
<!-- Link groups -->
<div class="footer-links-grid">
<div class="footer-group">
<h3 class="footer-group-title">Product</h3>
<a href="#" class="footer-link">Library</a>
<a href="#" class="footer-link">Lab</a>
<a href="#" class="footer-link">Collections</a>
<a href="#" class="footer-link">Changelog</a>
<a href="#" class="footer-link">Roadmap</a>
</div>
<div class="footer-group">
<h3 class="footer-group-title">Resources</h3>
<a href="#" class="footer-link">Documentation</a>
<a href="#" class="footer-link">API Reference</a>
<a href="#" class="footer-link">MCP Server</a>
<a href="#" class="footer-link">Open Source</a>
</div>
<div class="footer-group">
<h3 class="footer-group-title">Company</h3>
<a href="#" class="footer-link">About</a>
<a href="#" class="footer-link">Blog</a>
<a href="#" class="footer-link">Showcase</a>
<a href="#" class="footer-link">Contact</a>
</div>
<div class="footer-group">
<h3 class="footer-group-title">Newsletter</h3>
<p class="footer-newsletter-desc">Get new resources in your inbox.</p>
<form class="footer-newsletter-form" id="newsletterForm" novalidate>
<input type="email" class="newsletter-input" id="newsletterEmail" placeholder="you@example.com"
aria-label="Email address" />
<button type="submit" class="newsletter-btn">Subscribe</button>
</form>
<p class="newsletter-msg" id="newsletterMsg" aria-live="polite" hidden></p>
</div>
</div>
</div>
<!-- Legal row -->
<div class="footer-legal">
<span>© 2026 StealThis. All rights reserved.</span>
<div class="legal-links">
<a href="#" class="legal-link">Privacy Policy</a>
<a href="#" class="legal-link">Terms of Service</a>
<a href="#" class="legal-link">Cookie Policy</a>
</div>
</div>
</footer>
<script src="script.js"></script>
</body>
</html>Footer Links
A full-featured site footer with logo + tagline, 4-column link groups, newsletter subscription input with inline validation, social media icon row, and a bottom legal/copyright bar.
Features
- 4-column responsive grid that stacks to 2 columns on tablet and 1 on mobile
- Newsletter email input with simple JS validation and success feedback
- Social icon links (GitHub, Twitter/X, Discord, LinkedIn) with hover transitions
- Legal row: copyright text + Privacy and Terms links
- Dark background contrasting your site’s main palette
How it works
- Grid uses
display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr))for responsive columns - Newsletter JS: validates email format, shows success checkmark, resets after 3 s
- SVG social icons are inline for zero-dependency icon rendering