Selector

At-rules

@keyframes, @media, @font-face and the other CSS at-rules work inside a doodle. Only names css-doodle knows, like @grid or @cell, are treated specially.

@keyframes

Keyframes can be declared anywhere, even inside a cell rule, and are hoisted to the top of the stylesheet. Functions work inside the steps, and even in the step selectors. If the steps use functions, each cell gets its own @keyframes name so the random values differ. If they don’t, every cell shares one animation.

@grid: 6 / 60vmin _2px;
background: #000;
animation: spin @r(2s, 5s) linear infinite;
animation-delay: @r(-5s);

@keyframes spin {
  from { rotate: 0deg }
  to   { rotate: @p(360deg, -360deg) }
}

When the same name is declared inside a cell rule without functions, every selected cell shares that one animation:

@grid: 8 / 60vmin _2px;
background: #000;

@cell(random .3) {
  animation: pulse 1s ease-in-out infinite alternate;
  @keyframes pulse {
    to { scale: .2; background: #e6437d }
  }
}

Group rules

@media, @supports, @container, @layer, @scope and @starting-style wrap their contents like CSS does:

@grid: 5 / 60vmin _1px;
background: #000;

@media (hover: hover) {
  :hover {
    background: #e6437d;
  }
}

@media (prefers-color-scheme: dark) {
  background: #fff;
}

Other at-rules

Any other block starting with @, such as @font-face, is copied to the top of the stylesheet as written. Single-line statements like @import are emitted as written too.

@import url(fonts.css);

@font-face {
  font-family: Doodle;
  src: url(doodle.woff2);
}

@grid: 5 / 60vmin;
font-family: Doodle;

For Google fonts there is a shortcut, @google-font.

See also