CSS Banners & Alerts 01 / 14
Dismissible CSS Alert with Close Button
Four dismissible CSS alerts in a dark editorial magazine aesthetic — ink-on-paper texture, Playfair Display headlines, and four variant alerts (Critical / Dispatch / Verified / Memo) each with a unique colour story.
Best foreditorial magazines, content sites, admin notification trays, dashboard message centres.
The code
<section class="ba-dis" aria-label="Dismissible CSS alert demo">
<span class="section-label">— Alerts & Dispatches —</span>
<div class="alert alert--critical" data-ba-dis-alert="a1">
<div class="alert-inner">
<div class="alert-accent" aria-hidden="true"></div>
<div class="alert-body">
<span class="alert-tag">Critical · System</span>
<div class="alert-divider" aria-hidden="true"></div>
<p class="alert-headline">Authentication service is temporarily unavailable.</p>
<p class="alert-text">Our engineers have identified the issue and are working to restore access. Estimated resolution in 12–18 minutes. Existing sessions remain active.</p>
</div>
<button class="alert-close" type="button" data-ba-dis-dismiss="a1" aria-label="Dismiss">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
</div>
<div class="alert alert--dispatch" data-ba-dis-alert="a2">
<div class="alert-inner">
<div class="alert-accent" aria-hidden="true"></div>
<div class="alert-body">
<span class="alert-tag">Dispatch · Notice</span>
<div class="alert-divider" aria-hidden="true"></div>
<p class="alert-headline">Scheduled maintenance window this Friday.</p>
<p class="alert-text">The platform will undergo routine updates between 02:00–04:00 UTC. Some features may be temporarily inaccessible. No data loss is expected.</p>
</div>
<button class="alert-close" type="button" data-ba-dis-dismiss="a2" aria-label="Dismiss">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
</div>
<div class="alert alert--verified" data-ba-dis-alert="a3">
<div class="alert-inner">
<div class="alert-accent" aria-hidden="true"></div>
<div class="alert-body">
<span class="alert-tag">Verified · Confirmation</span>
<div class="alert-divider" aria-hidden="true"></div>
<p class="alert-headline">Your identity has been successfully verified.</p>
<p class="alert-text">Two-factor authentication is now active on your account. You can manage your security preferences from the account dashboard.</p>
</div>
<button class="alert-close" type="button" data-ba-dis-dismiss="a3" aria-label="Dismiss">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
</div>
<div class="alert alert--memo" data-ba-dis-alert="a4">
<div class="alert-inner">
<div class="alert-accent" aria-hidden="true"></div>
<div class="alert-body">
<span class="alert-tag">Memo · General</span>
<div class="alert-divider" aria-hidden="true"></div>
<p class="alert-headline">New privacy policy takes effect July 1st.</p>
<p class="alert-text">We've updated our terms of service to reflect recent regulatory changes. Please review the updated document before the effective date to remain compliant.</p>
</div>
<button class="alert-close" type="button" data-ba-dis-dismiss="a4" aria-label="Dismiss">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
</div>
<div class="restore-hint" data-ba-dis-restore aria-live="polite"></div>
</section> <section class="ba-dis" aria-label="Dismissible CSS alert demo">
<span class="section-label">— Alerts & Dispatches —</span>
<div class="alert alert--critical" data-ba-dis-alert="a1">
<div class="alert-inner">
<div class="alert-accent" aria-hidden="true"></div>
<div class="alert-body">
<span class="alert-tag">Critical · System</span>
<div class="alert-divider" aria-hidden="true"></div>
<p class="alert-headline">Authentication service is temporarily unavailable.</p>
<p class="alert-text">Our engineers have identified the issue and are working to restore access. Estimated resolution in 12–18 minutes. Existing sessions remain active.</p>
</div>
<button class="alert-close" type="button" data-ba-dis-dismiss="a1" aria-label="Dismiss">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
</div>
<div class="alert alert--dispatch" data-ba-dis-alert="a2">
<div class="alert-inner">
<div class="alert-accent" aria-hidden="true"></div>
<div class="alert-body">
<span class="alert-tag">Dispatch · Notice</span>
<div class="alert-divider" aria-hidden="true"></div>
<p class="alert-headline">Scheduled maintenance window this Friday.</p>
<p class="alert-text">The platform will undergo routine updates between 02:00–04:00 UTC. Some features may be temporarily inaccessible. No data loss is expected.</p>
</div>
<button class="alert-close" type="button" data-ba-dis-dismiss="a2" aria-label="Dismiss">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
</div>
<div class="alert alert--verified" data-ba-dis-alert="a3">
<div class="alert-inner">
<div class="alert-accent" aria-hidden="true"></div>
<div class="alert-body">
<span class="alert-tag">Verified · Confirmation</span>
<div class="alert-divider" aria-hidden="true"></div>
<p class="alert-headline">Your identity has been successfully verified.</p>
<p class="alert-text">Two-factor authentication is now active on your account. You can manage your security preferences from the account dashboard.</p>
</div>
<button class="alert-close" type="button" data-ba-dis-dismiss="a3" aria-label="Dismiss">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
</div>
<div class="alert alert--memo" data-ba-dis-alert="a4">
<div class="alert-inner">
<div class="alert-accent" aria-hidden="true"></div>
<div class="alert-body">
<span class="alert-tag">Memo · General</span>
<div class="alert-divider" aria-hidden="true"></div>
<p class="alert-headline">New privacy policy takes effect July 1st.</p>
<p class="alert-text">We've updated our terms of service to reflect recent regulatory changes. Please review the updated document before the effective date to remain compliant.</p>
</div>
<button class="alert-close" type="button" data-ba-dis-dismiss="a4" aria-label="Dismiss">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
</div>
<div class="restore-hint" data-ba-dis-restore aria-live="polite"></div>
</section>/* ─── 01 Dismissible CSS Alert — editorial magazine aesthetic ──── */
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,700;0,900;1,700&family=DM+Mono:wght@300;400;500&display=swap');
.ba-dis {
--ba-dis-ink: #0d0d0d;
--ba-dis-paper: #f5f0e8;
--ba-dis-cream: #ede7d5;
--ba-dis-accent-red: #c0392b;
--ba-dis-accent-gold: #b8860b;
--ba-dis-accent-teal: #1a7a6e;
--ba-dis-accent-slate: #4a5568;
--ba-dis-rule: #2d2d2d;
position: relative;
width: 100%;
min-height: 540px;
background: var(--ba-dis-paper);
background-image: repeating-linear-gradient(0deg, transparent, transparent 28px, rgba(0,0,0,0.04) 28px, rgba(0,0,0,0.04) 29px);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 20px;
padding: 48px 24px;
font-family: 'DM Mono', monospace;
box-sizing: border-box;
}
.ba-dis *, .ba-dis *::before, .ba-dis *::after { box-sizing: border-box; margin: 0; padding: 0; }
.ba-dis .alert { width: 100%; max-width: 680px; border-top: 3px solid var(--ba-dis-rule); border-bottom: 1px solid var(--ba-dis-rule); padding: 0; position: relative; overflow: hidden; transition: all 0.45s cubic-bezier(0.4, 0, 0.2, 1); transform-origin: top center; }
.ba-dis .alert.dismissed { opacity: 0; transform: scaleY(0); max-height: 0 !important; padding: 0; border-width: 0; margin: 0; pointer-events: none; }
.ba-dis .alert-inner { display: flex; align-items: stretch; gap: 0; }
.ba-dis .alert-accent { width: 6px; flex-shrink: 0; }
.ba-dis .alert-body { flex: 1; padding: 18px 20px; }
.ba-dis .alert-tag { font-family: 'DM Mono', monospace; font-size: 9px; font-weight: 500; letter-spacing: 0.22em; text-transform: uppercase; display: block; margin-bottom: 6px; opacity: 0.6; }
.ba-dis .alert-headline { font-family: 'Playfair Display', serif; font-size: 17px; font-weight: 700; line-height: 1.3; color: var(--ba-dis-ink); margin-bottom: 4px; }
.ba-dis .alert-text { font-size: 12px; line-height: 1.7; color: #444; font-weight: 300; }
.ba-dis .alert-close { flex-shrink: 0; width: 52px; display: flex; align-items: center; justify-content: center; cursor: pointer; border: none; background: transparent; border-left: 1px solid rgba(0,0,0,0.1); transition: background 0.2s ease; font-family: 'DM Mono', monospace; color: var(--ba-dis-ink); opacity: 0.45; padding: 0; }
.ba-dis .alert-close:hover { opacity: 1; background: rgba(0,0,0,0.05); }
.ba-dis .alert-close svg { width: 16px; height: 16px; }
.ba-dis .alert--critical { background: var(--ba-dis-ink); border-color: var(--ba-dis-accent-red); }
.ba-dis .alert--critical .alert-accent { background: var(--ba-dis-accent-red); }
.ba-dis .alert--critical .alert-tag { color: var(--ba-dis-accent-red); opacity: 0.8; }
.ba-dis .alert--critical .alert-headline { color: var(--ba-dis-paper); }
.ba-dis .alert--critical .alert-text { color: rgba(245,240,232,0.65); }
.ba-dis .alert--critical .alert-close { color: var(--ba-dis-paper); border-left-color: rgba(255,255,255,0.1); }
.ba-dis .alert--dispatch { background: var(--ba-dis-cream); border-color: var(--ba-dis-accent-gold); }
.ba-dis .alert--dispatch .alert-accent { background: var(--ba-dis-accent-gold); }
.ba-dis .alert--dispatch .alert-tag { color: var(--ba-dis-accent-gold); }
.ba-dis .alert--verified { background: #f0faf8; border-color: var(--ba-dis-accent-teal); }
.ba-dis .alert--verified .alert-accent { background: var(--ba-dis-accent-teal); }
.ba-dis .alert--verified .alert-tag { color: var(--ba-dis-accent-teal); }
.ba-dis .alert--memo { background: var(--ba-dis-paper); border-color: var(--ba-dis-accent-slate); }
.ba-dis .alert--memo .alert-accent { background: var(--ba-dis-accent-slate); }
.ba-dis .alert--memo .alert-tag { color: var(--ba-dis-accent-slate); }
.ba-dis .alert-divider { width: 24px; height: 1px; background: currentColor; opacity: 0.25; margin: 8px 0; }
.ba-dis .restore-hint { font-size: 10px; font-family: 'DM Mono', monospace; color: #999; letter-spacing: 0.12em; text-align: center; min-height: 20px; }
.ba-dis .restore-btn { background: none; border: none; cursor: pointer; color: var(--ba-dis-accent-teal); font-family: 'DM Mono', monospace; font-size: 10px; text-decoration: underline; letter-spacing: 0.12em; padding: 0; }
.ba-dis .section-label { font-family: 'DM Mono', monospace; font-size: 9px; letter-spacing: 0.3em; text-transform: uppercase; color: #aaa; align-self: flex-start; }
@media (prefers-reduced-motion: reduce) { .ba-dis .alert { transition: opacity 0.2s ease; } } /* ─── 01 Dismissible CSS Alert — editorial magazine aesthetic ──── */
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,700;0,900;1,700&family=DM+Mono:wght@300;400;500&display=swap');
.ba-dis {
--ba-dis-ink: #0d0d0d;
--ba-dis-paper: #f5f0e8;
--ba-dis-cream: #ede7d5;
--ba-dis-accent-red: #c0392b;
--ba-dis-accent-gold: #b8860b;
--ba-dis-accent-teal: #1a7a6e;
--ba-dis-accent-slate: #4a5568;
--ba-dis-rule: #2d2d2d;
position: relative;
width: 100%;
min-height: 540px;
background: var(--ba-dis-paper);
background-image: repeating-linear-gradient(0deg, transparent, transparent 28px, rgba(0,0,0,0.04) 28px, rgba(0,0,0,0.04) 29px);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 20px;
padding: 48px 24px;
font-family: 'DM Mono', monospace;
box-sizing: border-box;
}
.ba-dis *, .ba-dis *::before, .ba-dis *::after { box-sizing: border-box; margin: 0; padding: 0; }
.ba-dis .alert { width: 100%; max-width: 680px; border-top: 3px solid var(--ba-dis-rule); border-bottom: 1px solid var(--ba-dis-rule); padding: 0; position: relative; overflow: hidden; transition: all 0.45s cubic-bezier(0.4, 0, 0.2, 1); transform-origin: top center; }
.ba-dis .alert.dismissed { opacity: 0; transform: scaleY(0); max-height: 0 !important; padding: 0; border-width: 0; margin: 0; pointer-events: none; }
.ba-dis .alert-inner { display: flex; align-items: stretch; gap: 0; }
.ba-dis .alert-accent { width: 6px; flex-shrink: 0; }
.ba-dis .alert-body { flex: 1; padding: 18px 20px; }
.ba-dis .alert-tag { font-family: 'DM Mono', monospace; font-size: 9px; font-weight: 500; letter-spacing: 0.22em; text-transform: uppercase; display: block; margin-bottom: 6px; opacity: 0.6; }
.ba-dis .alert-headline { font-family: 'Playfair Display', serif; font-size: 17px; font-weight: 700; line-height: 1.3; color: var(--ba-dis-ink); margin-bottom: 4px; }
.ba-dis .alert-text { font-size: 12px; line-height: 1.7; color: #444; font-weight: 300; }
.ba-dis .alert-close { flex-shrink: 0; width: 52px; display: flex; align-items: center; justify-content: center; cursor: pointer; border: none; background: transparent; border-left: 1px solid rgba(0,0,0,0.1); transition: background 0.2s ease; font-family: 'DM Mono', monospace; color: var(--ba-dis-ink); opacity: 0.45; padding: 0; }
.ba-dis .alert-close:hover { opacity: 1; background: rgba(0,0,0,0.05); }
.ba-dis .alert-close svg { width: 16px; height: 16px; }
.ba-dis .alert--critical { background: var(--ba-dis-ink); border-color: var(--ba-dis-accent-red); }
.ba-dis .alert--critical .alert-accent { background: var(--ba-dis-accent-red); }
.ba-dis .alert--critical .alert-tag { color: var(--ba-dis-accent-red); opacity: 0.8; }
.ba-dis .alert--critical .alert-headline { color: var(--ba-dis-paper); }
.ba-dis .alert--critical .alert-text { color: rgba(245,240,232,0.65); }
.ba-dis .alert--critical .alert-close { color: var(--ba-dis-paper); border-left-color: rgba(255,255,255,0.1); }
.ba-dis .alert--dispatch { background: var(--ba-dis-cream); border-color: var(--ba-dis-accent-gold); }
.ba-dis .alert--dispatch .alert-accent { background: var(--ba-dis-accent-gold); }
.ba-dis .alert--dispatch .alert-tag { color: var(--ba-dis-accent-gold); }
.ba-dis .alert--verified { background: #f0faf8; border-color: var(--ba-dis-accent-teal); }
.ba-dis .alert--verified .alert-accent { background: var(--ba-dis-accent-teal); }
.ba-dis .alert--verified .alert-tag { color: var(--ba-dis-accent-teal); }
.ba-dis .alert--memo { background: var(--ba-dis-paper); border-color: var(--ba-dis-accent-slate); }
.ba-dis .alert--memo .alert-accent { background: var(--ba-dis-accent-slate); }
.ba-dis .alert--memo .alert-tag { color: var(--ba-dis-accent-slate); }
.ba-dis .alert-divider { width: 24px; height: 1px; background: currentColor; opacity: 0.25; margin: 8px 0; }
.ba-dis .restore-hint { font-size: 10px; font-family: 'DM Mono', monospace; color: #999; letter-spacing: 0.12em; text-align: center; min-height: 20px; }
.ba-dis .restore-btn { background: none; border: none; cursor: pointer; color: var(--ba-dis-accent-teal); font-family: 'DM Mono', monospace; font-size: 10px; text-decoration: underline; letter-spacing: 0.12em; padding: 0; }
.ba-dis .section-label { font-family: 'DM Mono', monospace; font-size: 9px; letter-spacing: 0.3em; text-transform: uppercase; color: #aaa; align-self: flex-start; }
@media (prefers-reduced-motion: reduce) { .ba-dis .alert { transition: opacity 0.2s ease; } }(() => {
// Scoped dismiss/restore wiring. Multiple instances of this demo can
// coexist on one page — each tracks its own dismissed set bound to
// the wrapper element. No global ids, no document-level listeners.
const root = document.querySelector('.ba-dis');
if (!root) return;
const restore = root.querySelector('[data-ba-dis-restore]');
const labels = { a1: 'Critical', a2: 'Dispatch', a3: 'Verified', a4: 'Memo' };
const dismissed = {};
function paintRestore() {
const keys = Object.keys(dismissed);
if (keys.length === 0) { restore.innerHTML = ''; return; }
restore.innerHTML = 'Dismissed: ' + keys.map(k =>
'<button class="restore-btn" type="button" data-ba-dis-restore-btn="' + k + '">' + labels[k] + '</button>'
).join(' · ');
}
root.addEventListener('click', (e) => {
const dismissBtn = e.target.closest('[data-ba-dis-dismiss]');
if (dismissBtn) {
const id = dismissBtn.dataset.baDisDismiss;
const el = root.querySelector('[data-ba-dis-alert="' + id + '"]');
if (el) { el.classList.add('dismissed'); dismissed[id] = true; paintRestore(); }
return;
}
const restoreBtn = e.target.closest('[data-ba-dis-restore-btn]');
if (restoreBtn) {
const id = restoreBtn.dataset.baDisRestoreBtn;
const el = root.querySelector('[data-ba-dis-alert="' + id + '"]');
if (el) { el.classList.remove('dismissed'); delete dismissed[id]; paintRestore(); }
}
});
})(); (() => {
// Scoped dismiss/restore wiring. Multiple instances of this demo can
// coexist on one page — each tracks its own dismissed set bound to
// the wrapper element. No global ids, no document-level listeners.
const root = document.querySelector('.ba-dis');
if (!root) return;
const restore = root.querySelector('[data-ba-dis-restore]');
const labels = { a1: 'Critical', a2: 'Dispatch', a3: 'Verified', a4: 'Memo' };
const dismissed = {};
function paintRestore() {
const keys = Object.keys(dismissed);
if (keys.length === 0) { restore.innerHTML = ''; return; }
restore.innerHTML = 'Dismissed: ' + keys.map(k =>
'<button class="restore-btn" type="button" data-ba-dis-restore-btn="' + k + '">' + labels[k] + '</button>'
).join(' · ');
}
root.addEventListener('click', (e) => {
const dismissBtn = e.target.closest('[data-ba-dis-dismiss]');
if (dismissBtn) {
const id = dismissBtn.dataset.baDisDismiss;
const el = root.querySelector('[data-ba-dis-alert="' + id + '"]');
if (el) { el.classList.add('dismissed'); dismissed[id] = true; paintRestore(); }
return;
}
const restoreBtn = e.target.closest('[data-ba-dis-restore-btn]');
if (restoreBtn) {
const id = restoreBtn.dataset.baDisRestoreBtn;
const el = root.querySelector('[data-ba-dis-alert="' + id + '"]');
if (el) { el.classList.remove('dismissed'); delete dismissed[id]; paintRestore(); }
}
});
})();More from CSS Banners & Alerts
Sticky Top Announcement Banner CSSCSS Cookie Consent Banner BottomCSS Alert Banner with Icon AlignmentCSS Toast Notification Alert Top RightCSS Banner with Diagonal Slash BackgroundCSS Gradient Animated Border AlertSemantic Bootstrap-style Alerts CSSInline Form Validation Alert CSSCSS Pulsing Banner for Live UpdatesMinimalist Border Left CSS AlertResponsive Full Width Hero Banner CSSMaterial Design Floating Alert Card
View the full collection →