Theme
Design your own
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