Theme
On this page (4)
Component Skill — components/code-block/component-skill.md

Native basis

A <figure>: a header with radio "tabs" (or a file name) and a copy button, then one <pre><code> per tab (data-tab, shown with :has(:checked)); lines as <span>s get counters and data-highlight.

Web Platform APIs

:has()CSS countersClipboard API<kbd>

Classes

.mk-code-block.mk-code-block-head.mk-code-block-file.mk-code-block-tabs.mk-code-block-copy.mk-code-block-c.mk-code-block-k.mk-code-block-s.mk-code-block-status

Data attributes

data-variant: file, inline; data-tab on panels; data-highlight on lines; data-numbers on <pre>.

§Default

Radio "tabs" switch the install command - read by :has(), no script. The copy button uses the Clipboard API (one line of page script) and announces "Copied".

§File

data-variant='file': the file name in the header, line numbers from a CSS counter (data-numbers) and two highlighted lines (data-highlight).

§Inline

data-variant='inline': one command on a line - the prompt ($) is drawn by CSS and never copied.

§CSS view file

/* -- Code Example (website · Docs & Help) ---------------------------------
   Displays code with optional language tabs and copying controls - tabs for each package manager, a file header, highlighted lines, or one command to copy. */
@layer components {
  /* every box in the block measures border-box - the same on any page */
  :where(.mk-code-block, .mk-code-block *, .mk-code-block ::before, .mk-code-block ::after) { box-sizing: border-box; }
  .mk-code-block { margin: 0; width: 100%; overflow: hidden; border: 1px solid oklch(0.3 0.01 260); border-radius: var(--radius-lg); background: oklch(0.17 0.01 260); color: oklch(0.92 0 0); }
  .mk-code-block-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.375rem 0.375rem 0.375rem 0.75rem; border-block-end: 1px solid oklch(0.3 0.01 260); font-size: 0.8125rem; }
  .mk-code-block-file { display: inline-flex; align-items: center; gap: 0.375rem; color: oklch(0.75 0 0); font-family: var(--font-mono);
    & svg { width: 0.875rem; height: 0.875rem; }
  }
  .mk-code-block-tabs { display: flex; gap: 0.125rem;
    & label { position: relative; padding: 0.25rem 0.625rem; border-radius: var(--radius-sm); color: oklch(0.7 0 0); font-family: var(--font-mono); cursor: pointer; }
    & input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
    & label:has(:checked) { background: oklch(0.28 0.01 260); color: #fff; }
    & label:has(:focus-visible) { outline: 2px solid oklch(0.7 0.12 250); outline-offset: 1px; }
  }
  .mk-code-block-copy { display: grid; place-items: center; width: 2rem; height: 2rem; padding: 0; border: 0; border-radius: var(--radius-sm); background: transparent; color: oklch(0.75 0 0); cursor: pointer;
    & svg { width: 1rem; height: 1rem; }
    &:hover { background: oklch(0.28 0.01 260); color: #fff; }
    &:focus-visible { outline: 2px solid oklch(0.7 0.12 250); outline-offset: 1px; }
  }
  .mk-code-block-copy[data-copied] { color: oklch(0.75 0.15 150); }
  /* reset whatever the page styles pre / code with: the block owns its look */
  .mk-code-block pre { margin: 0; padding: 1rem 0; overflow-x: auto; border: 0; border-radius: 0; background: none; box-shadow: none; color: inherit; font-family: var(--font-mono); font-size: 0.8125rem; line-height: 1.7; }
  .mk-code-block code { display: grid; padding: 0; border: 0; background: none; color: inherit; font-family: inherit; font-size: inherit; }
  .mk-code-block code > span { display: block; padding-inline: 1rem; white-space: pre; }
  .mk-code-block pre[data-numbers] code { counter-reset: mk-line; }
  .mk-code-block pre[data-numbers] code > span::before { counter-increment: mk-line; content: counter(mk-line); display: inline-block; width: 2rem; margin-inline-end: 1rem; color: oklch(0.5 0 0); text-align: end; user-select: none; }
  .mk-code-block code > span[data-highlight] { background: oklch(0.6 0.12 250 / 0.16); box-shadow: inset 3px 0 0 oklch(0.7 0.14 250); }
  .mk-code-block-c { color: oklch(0.6 0 0); }
  .mk-code-block-k { color: oklch(0.78 0.13 300); }
  .mk-code-block-s { color: oklch(0.8 0.13 150); }
  .mk-code-block [data-tab] { display: none; }
  .mk-code-block:has(input[value="npm"]:checked) [data-tab="npm"],
  .mk-code-block:has(input[value="pnpm"]:checked) [data-tab="pnpm"],
  .mk-code-block:has(input[value="bun"]:checked) [data-tab="bun"] { display: block; }
  .mk-code-block-status { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .mk-code-block[data-variant="inline"] {
    display: flex;
    align-items: center;
    max-width: 30rem;
    & pre { flex: 1; padding: 0.625rem 0; }
    & code > span::before { content: "$ "; color: oklch(0.55 0 0); user-select: none; }
    & .mk-code-block-copy { margin-inline-end: 0.375rem; }
  }
  /* -- Accessibility ------------------------------------------- */
  @media (forced-colors: active) {
    .mk-code-block { border-color: CanvasText; }
    .mk-code-block code > span[data-highlight] { outline: 1px solid Highlight; }
  }
}

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