WebCraft

Catalogue

Every element, with the caveat that comes with it

81 interface elements, each rendered live on its own page with the source and the one thing that breaks it.

  1. Hover that stays off touchscreens @media (hover: hover) hover
  2. The filled half of a range track ::-moz-range-progress form
  3. Numbering the browser keeps for you counters() text
  4. An underline you actually drew text-underline-offset type
  5. Type on rails, not on stops clamp() type
  6. The fixed element that stopped meaning it fixed under transform layout
  7. A shadow that knows the shape filter: drop-shadow() surface
  8. The long word that will not bend overflow-wrap: anywhere text
  9. An ellipsis is three declarations, not one text-overflow: ellipsis text
  10. Less motion is not no motion prefers-reduced-motion motion
  11. A layout drawn as a picture of itself grid-template-areas layout
  12. Four faint shadows beat one dark one box-shadow ×4 surface
  13. Five colours out of one token oklch(from …) surface
  14. Hidden from eyes, kept for readers .visually-hidden a11y
  15. The link only keyboards ever meet skip link + :focus a11y
  16. The same two colours, mixed two ways color-mix() surface
  17. Why the last row stretches, and how to stop it auto-fit vs auto-fill layout
  18. Centring with no flex and no grid align-content (block) layout
  19. An edge that fades instead of cutting mask-composite: intersect scroll
  20. A vertical label that does not break the box writing-mode: vertical-rl layout
  21. A heading that sits on its own cap height text-box: trim-both type
  22. Type that inverts itself over anything mix-blend-mode: difference surface
  23. An outline that does not eat the letters paint-order: stroke fill type
  24. A drop cap the browser measures for you initial-letter text
  25. Stripes that stay right when rows are filtered :nth-child(of S) table
  26. One declaration that covers both themes light-dark() surface
  27. Carousel dots the browser draws itself ::scroll-marker scroll
  28. A tooltip that follows its anchor with no JavaScript anchor-name + position-area layout
  29. Styles that stop at a boundary you name @scope layout
  30. Animating height to auto, finally interpolate-size motion
  31. A spring in the easing function linear() motion
  32. Type that wraps to a curve, not a box shape-outside type
  33. Reveal on scroll, with no observer animation-timeline: view() motion
  34. Clipping that leaves sticky alone overflow: clip layout
  35. A dropdown a keyboard can hold open :focus-within a11y
  36. Avatars that never squash object-fit: cover media
  37. An underline that slides in background-size hover
  38. An analog clock wound by one line of JavaScript animation-delay: -43200s motion
  39. The logo that never hits the corner animation + cqw motion
  40. resize keeps writing after max-width stops it resize + max-width layout
  41. A gradient border that keeps its corners background + padding surface
  42. A spotlight that follows the cursor radial-gradient at var() hover
  43. A progress bar tied to scroll, with no JavaScript animation-timeline: scroll() motion
  44. A table header that stays put position: sticky table
  45. Cut a paragraph to three lines -webkit-line-clamp text
  46. A textarea that grows as you type field-sizing: content form
  47. An accordion with no JavaScript <details name> disclosure
  48. A focus ring for keyboards only :focus-visible a11y
  49. A wide table that keeps its first column position: sticky (inline) table
  50. Shadows that show there is more to scroll background-attachment: local scroll
  51. A segmented control with a sliding indicator :has() + translate control
  52. A skeleton that does not lie about the layout @keyframes + gradient loading
  53. A menu button that turns into a close button aria-expanded menu
  54. A switch that is still a checkbox appearance: none form
  55. A marquee that never jumps translateX(-50%) motion
  56. Frosted glass over anything backdrop-filter surface
  57. Type painted with a gradient background-clip: text type
  58. A range slider you can actually style ::-webkit-slider-thumb form
  59. A card that tips towards the cursor perspective + rotate hover
  60. A gradient angle that actually animates @property motion
  61. A card that reads its own container, not the window @container layout
  62. Type that scales with its container cqi layout
  63. Boxes that keep their proportions aspect-ratio layout
  64. A heading that breaks where a typesetter would text-wrap: balance type
  65. Paragraphs with no orphan last line text-wrap: pretty type
  66. Hyphenation in a narrow column hyphens: auto type
  67. An error state that waits its turn :user-invalid form
  68. Native controls in your palette accent-color form
  69. A label that floats out of the way :placeholder-shown form
  70. A carousel the browser drives scroll-snap-type scroll
  71. Scrolling that stops at the edge overscroll-behavior scroll
  72. Anchor links that clear a sticky header scroll-padding-top scroll
  73. A wrapper that knows its input is wrong :has() state
  74. Hovering one row quiets the others :has() + :not() hover
  75. A layout that changes when the list gets long :has(:nth-child()) layout
  76. A modal that traps focus for you showModal() dialog
  77. A popover with no JavaScript at all popovertarget dialog
  78. A section the page cannot reach inert a11y
  79. Animating something in from display: none @starting-style motion
  80. The exit animation, which is the hard half allow-discrete motion
  81. Reordering a list without it jumping startViewTransition() motion