Theme
On this page (6)
Component Skill — components/blog-header/component-skill.md

Native basis

A <header> with the title (h1), an editorial description, optional actions (Buttons - subscribe, RSS) and a <nav> of category links; aria-current marks the current category. Each category is a real URL - no filter script.

Built from

Button, Input, Toggle Group, Select.

Web Platform APIs

aria-currentContainer queriescolor-mix()

Classes

.mk-blog-header.mk-blog-header-copy.mk-blog-header-eyebrow.mk-blog-header-title.mk-blog-header-desc.mk-blog-header-actions.mk-blog-header-categories.mk-blog-header-count.mk-blog-header-toolbar.mk-blog-header-subscribe.mk-blog-header-media

Data attributes

data-align="center", data-variant="banner"; aria-current on the current category; data-variant (split, editorial); .mk-blog-header-media, .mk-blog-header-subscribe, .mk-blog-header-toolbar, .mk-blog-header-count.

§Default

Eyebrow, title, description, subscribe + RSS actions and the categories - the current one filled (aria-current).

§Centered banner

data-variant='banner' with data-align='center': the header on a muted surface with a soft primary glow.

§Split with subscribe

data-variant='split': the copy beside a featured image; an inline subscribe form (Input + Button) replaces the actions. Narrow the demo and the image moves under the copy.

§Search, view and sort

A toolbar row under the categories: a search Input, a Toggle Group for the view and a Select for the order. The chips carry counts.

§Editorial

data-variant='editorial': a serif italic masthead between ornaments, the categories as underlined text - a magazine.

§CSS view file

/* -- Blog Header (website) ------------------------------------------
   Introduces a blog: eyebrow, title, editorial description, optional
   actions (subscribe, RSS) and the category chips - the current category
   marked with aria-current. Centered, or set on a banner surface. */
@layer components {
  .mk-blog-header {
    container: mk-blog-header / inline-size;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.25rem;
    box-sizing: border-box;
    width: 100%;
    max-width: 80rem;
    margin-inline: auto;
    padding-inline: 1.25rem;
  }
  .mk-blog-header-copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    max-width: 46rem;
  }
  .mk-blog-header-eyebrow { color: var(--primary); font-size: 0.875rem; font-weight: 500; }
  .mk-blog-header-title {
    margin: 0;
    font-size: 2.25rem;
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -0.03em;
    text-wrap: balance;
  }
  .mk-blog-header-desc {
    margin: 0;
    color: var(--muted-foreground);
    font-size: 1.0625rem;
    line-height: 1.6;
    text-wrap: pretty;
  }
  .mk-blog-header-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
  /* categories: chips, the current one filled */
  .mk-blog-header-categories {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    & a {
      display: inline-flex;
      align-items: center;
      gap: 0.375rem;
      padding: 0.3125rem 0.875rem;
      border: 1px solid var(--border);
      border-radius: 999px;
      color: var(--foreground);
      font-size: 0.8125rem;
      font-weight: 500;
      text-decoration: none;
      transition: background-color 120ms, border-color 120ms, color 120ms;
      &:hover { background: var(--accent); color: var(--accent-foreground); }
      &[aria-current] { border-color: var(--primary); background: var(--primary); color: var(--primary-foreground); }
      &:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
    }
  }
  .mk-blog-header[data-align="center"] {
    align-items: center;
    text-align: center;
    & .mk-blog-header-copy { align-items: center; }
    & :is(.mk-blog-header-actions, .mk-blog-header-categories) { justify-content: center; }
  }
  /* banner: the header on a muted surface */
  .mk-blog-header[data-variant="banner"] {
    padding: 2.5rem 1.5rem;
    border-radius: var(--radius-xl);
    background:
      radial-gradient(120% 140% at 0% 0%, color-mix(in oklch, var(--primary) 14%, transparent), transparent 60%),
      var(--muted);
  }
  /* a count inside a category chip */
  .mk-blog-header-categories a .mk-blog-header-count {
    padding: 0 0.375rem;
    border-radius: 999px;
    background: color-mix(in oklch, currentColor 12%, transparent);
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
  }
  /* a toolbar row: search on the left, view / sort on the right */
  .mk-blog-header-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    width: 100%;
    padding-block-start: 1rem;
    border-block-start: 1px solid var(--border);
  }
  /* an inline subscribe form: email + button */
  .mk-blog-header-subscribe {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    width: 100%;
    max-width: 26rem;
    & .input { flex: 1 1 12rem; }
  }
  /* split: the copy beside a featured image */
  .mk-blog-header[data-variant="split"] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
    align-items: center;
    gap: 2rem;
  }
  .mk-blog-header-media {
    margin: 0;
    overflow: hidden;
    border-radius: var(--radius-xl);
    background: var(--muted);
    box-shadow: var(--shadow-lg);
    rotate: 1.5deg;
    & img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
  }
  /* editorial: a serif masthead, centered between ornaments */
  .mk-blog-header[data-variant="editorial"] {
    align-items: center;
    text-align: center;
    & .mk-blog-header-copy { align-items: center; }
    & .mk-blog-header-eyebrow {
      display: flex;
      align-items: center;
      gap: 0.75rem;
      color: var(--muted-foreground);
      font-size: 0.75rem;
      letter-spacing: 0.2em;
      text-transform: uppercase;
      &::before, &::after { content: ""; width: 2.5rem; height: 1px; background: currentColor; }
    }
    & .mk-blog-header-title { font-family: var(--font-serif); font-weight: 700; font-style: italic; letter-spacing: -0.01em; }
    & .mk-blog-header-categories { justify-content: center; }
    & .mk-blog-header-categories a { border: 0; border-radius: 0; padding-inline: 0.25rem; }
    & .mk-blog-header-categories a[aria-current] { background: transparent; color: var(--foreground); box-shadow: inset 0 -2px var(--primary); }
  }
  @container mk-blog-header (min-width: 48rem) {
    .mk-blog-header-title { font-size: 3rem; }
  }
  /* -- Accessibility ------------------------------------------- */
  @media (prefers-reduced-motion: reduce) {
    .mk-blog-header-categories a { transition: none; }
  }
  @media (prefers-contrast: more) {
    .mk-blog-header-desc { color: var(--foreground); }
    .mk-blog-header-categories a { border-color: var(--foreground); }
  }
  @media (forced-colors: active) {
    .mk-blog-header-categories a[aria-current] { forced-color-adjust: none; background: Highlight; color: HighlightText; border-color: Highlight; }
  }
}

Comments, ideas or improvements? Edit this page's source on GitHub