CSS-Impress

responsive columns

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
.container {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

auto-resize textarea

textarea  { field-sizing: content; }

responsive padding w/o media query

Lorem ipsum dolor sit amet consectetur adipisicing elit. Animi corrupti obcaecati perferendis quaerat culpa odio voluptatum expedita tempora quam, in id, velit neque? Necessitatibus nisi dolores totam fugit adipisci voluptate, consequatur beatae asperiores quis, nihil quibusdam ullam nemo sequi natus?

p  { padding: min(3em, 9%); }

CSS-only responsive menu

/* 1. The hidden checkbox stores open/closed. Labels toggle it. */
#menuActive { display: none; }

/* 2. The MENU button is hidden on desktop */
.openMenu { display: none; }

@media (max-width: 700px) {            /* 3. breakpoint */
  .openMenu { display: block; }        /* show the button */

  ul {
    flex-direction: column;            /* stack the links */
    position: absolute;                /* real app would use fixed property */
    right: 200%;                       /* park the panel off-screen */
    transition: right 200ms ease-in-out;
    z-index: 10;                       /* above the overlay */
  }

  /* 4. checked = open */
  #menuActive:checked ~ nav ul { right: 0; }             /* slide in */
  #menuActive:checked ~ #overlay {
    display: block;
    position: absolute;
    inset: 0;                          /* shorthand for top/right/bottom/left: 0 */
    background: rgba(0, 0, 0, 0.5);    /* dim the page */
    z-index: 9;
  }
}

columns

.images {
  width: min(1000px, 100%);
  columns: 4 200px;     /* up to 4 columns, each at least 200px wide */
  column-gap: 0.5em;

  img {
    width: 100%;        /* fills its column */
    display: block;     /* removes the inline gap below each image */
    margin-bottom: 0.5em;
  }
}

relative padding

Lorem ipsum dolor sit amet consectetur adipisicing elit. Atque ipsum vel nemo, sed eaque obcaecati quaerat aut inventore id fuga!
.relative-padding {
  padding: min(5em, 8%);   /* 8% of the parent's width, capped at 5em */
}

responsive font-size

Lorem ipsum dolor sit amet consectetur adipisicing elit. Illum magnam officiis velit reprehenderit, omnis sequi cum voluptates dolore laborum qui.

h1 {
  /* clamp(min, preferred, max): grows with the viewport width,
     but never below 1.8rem or above 5rem */
  font-size: clamp(1.8rem, calc(7vw + 1rem), 5rem);
}

CSS-only headings counter

counter heading

another heading

and another

last header

.counted {
  counter-reset: headings;             /* start a counter named "headings" at 0 */

  h3 {
    counter-increment: headings;       /* +1 for every h3 */
    display: flex;
    gap: 0.75em;

    &::before {
      content: counter(headings);      /* print the current count as a badge */
      background: green;
      color: white;
      width: 40px;
      text-align: center;
    }
  }
}

corner shapes

notch and superellipse

.shape {
  border-radius: 50px;                   /* sets the size of each corner */
  corner-shape: superellipse(5) notch;   /* sets its shape; 2 values alternate */
  transition: all 400ms;                 /* corner shapes can animate */

  &:hover {
    corner-shape: notch superellipse(5); /* swap them on hover */
  }
}
/* other shapes: round, squircle, bevel, scoop, square */
/* Chromium only for now; elsewhere it falls back to plain rounded corners */

clip-path circle

.corners {
  background: green;
  border-radius: 55px;
  corner-shape: square scoop square square;  /* scoop the top-right corner inwards */

  &::after {
    content: '';
    background: red;
    clip-path: circle(50px at right top);    /* only a circle centred on the top-right corner shows */
  }
  &:hover { border-radius: 60px; }                          /* scoop grows... */
  &:hover::after { clip-path: circle(55px at right top); }  /* ...and so does the circle */
}

clip-path path

/* blue is ::before, not .custom: clip-path on .custom would clip the red ::after too */
.custom::before {
  background: blue;
  /* M move, H/V horizontal/vertical line, A arc, Z close.
     Traces the blue with the red's shape (+5px gap) cut out of the top-left */
  clip-path: path("M 205 0 H 400 V 200 H 0 V 105 H 180 A 25 25 0 0 0 205 80 Z");
}
.custom::after {
  width: 200px;
  height: 100px;
  background: red;
  border-radius: 20px;
  corner-shape: round square round square;
}
.custom:hover::before {
  /* same commands in the same order, so the path can animate */
  clip-path: path("M 210 0 H 400 V 200 H 0 V 110 H 185 A 25 25 0 0 0 210 85 Z");
}
.custom:hover::after {
  width: 205px;
  height: 105px;
}

clip-path freestyle


clip-path heart

.heart {
  width: 100px;                /* path() is in px, so the box must match the drawing */
  height: 90px;
  background: red;
  /* C c1x c1y c2x c2y x y: cubic curve, two control points.
     Clockwise from the bottom tip; the right half mirrors the left (x -> 100 - x) */
  clip-path: path("M 50 90 C 25 70 0 50 0 28 C 0 10 14 0 28 0 C 40 0 50 10 50 20 C 50 10 60 0 72 0 C 86 0 100 10 100 28 C 100 50 75 70 50 90 Z");
  transition: scale 200ms;

  &:hover { scale: 1.2; }      /* scale enlarges the clipped heart too */
}

border image

/* register --angle as a real <angle> so it can be animated */
@property --angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

.spinner {
  border: 8px solid black;   /* border-image paints into this width */
  border-image: conic-gradient(from var(--angle), blue, red, yellow, blue) 1;
  animation: 2s spin linear infinite;
}

@keyframes spin {
  from { --angle: 0deg; }
  to   { --angle: 360deg; }    /* rotates the gradient start point */
}
/* note: border-image ignores border-radius, so the corners stay square */

Raw SVG