@property

CSS ์ปค์Šคํ…€ ํ”„๋กœํผํ‹ฐ(--var)๋ฅผ ์“ฐ๋‹ค ๋ณด๋ฉด ์•„์‰ฌ์šด ๋ถ€๋ถ„๋“ค์ด ์žˆ๋Š”๋ฐ, ์ผ๋‹จ ์ž˜๋ชป๋œ ๊ฐ’์„ ๋„ฃ์–ด๋„ ์—๋Ÿฌ๊ฐ€ ๋‚˜์ง€ ์•Š๊ณ , ์ดˆ๊ธฐ๊ฐ’์ด๋‚˜ ์ƒ์† ์—ฌ๋ถ€๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์ œ์–ดํ•  ๋ฐฉ๋ฒ•๋„ ์—†๋‹ค. ์• ๋‹ˆ๋ฉ”์ด์…˜๋„ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐ๋„๋‚˜ ๊ธธ์ด ๊ฐ’์ด ์‹œ๊ฐ„์— ๋”ฐ๋ผ ๋ณ€ํ•˜๋Š” ํšจ๊ณผ๋ฅผ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ๊ฒฐ๊ตญ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ์˜์กดํ•ด์•ผ ํ–ˆ๋‹ค. ์ด๋Ÿฐ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด CSS Houdini API ์ค‘ ํ•˜๋‚˜๋กœ ๋“ฑ์žฅํ•œ ๊ฒƒ์ด ๋ฐ”๋กœ @property๋‹ค. CSS ์ปค์Šคํ…€ ํ”„๋กœํผํ‹ฐ์— ํƒ€์ž…, ์ดˆ๊ธฐ๊ฐ’, ์ƒ์† ์—ฌ๋ถ€ ๋“ฑ์„ ๋ช…์‹œ์ ์œผ๋กœ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ฃผ๋Š”๋ฐ, Baseline 2024์— ํฌํ•จ๋˜๋ฉด์„œ ์ฃผ์š” ๋ธŒ๋ผ์šฐ์ €์—์„œ๋„ ์•ˆ์ •์ ์œผ๋กœ ์“ธ ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ค€์ด ๋๋‹ค.

@property

@property๋Š” CSS ์•ˆ์—์„œ ์ปค์Šคํ…€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” at-rule์ด๋‹ค.
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ CSS.registerProperty()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ์ผ์„ CSS๋งŒ์œผ๋กœ ํ•  ์ˆ˜ ์žˆ๋‹ค.

@property --rotation {
  syntax: "<angle>";
  inherits: false;
  initial-value: 45deg;
}
  • syntax: ํ—ˆ์šฉํ•  ๊ฐ’์˜ ํƒ€์ž…์„ ์ง€์ •ํ•œ๋‹ค. ex) , , , , ๋“ฑ
  • inherits: ์ƒ์† ์—ฌ๋ถ€๋ฅผ ์„ค์ •ํ•œ๋‹ค.
  • initial-value: ์ดˆ๊ธฐ๊ฐ’์„ ์„ค์ •ํ•œ๋‹ค. ๋‹จ, ์ด ๊ฐ’์€ computationally independent ์ด์–ด์•ผ ํ•˜๋Š”๋ฐ, ์˜ˆ๋ฅผ ๋“ค์–ด 10px์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๋ถ€๋ชจ ํฐํŠธ ํฌ๊ธฐ์— ์˜์กดํ•˜๋Š” 3em์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

syntax์™€ inherits๋Š” ํ•„์ˆ˜๋‹ค. ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ผ๋„ ๋น ์ง€๋ฉด ์ „์ฒด @property ์„ ์–ธ์ด ๋ฌด์‹œ๋œ๋‹ค.
initial-value๋Š” ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ํ•„์ˆ˜์ธ๋ฐ, syntax: "*"๊ฐ€ ์•„๋‹ ๊ฒฝ์šฐ์—๋Š” ๋ฐ˜๋“œ์‹œ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

@property์™€ ์• ๋‹ˆ๋ฉ”์ด์…˜

์ผ๋ฐ˜ custom property๋Š” ๋ฌธ์ž์—ด๋กœ ์ทจ๊ธ‰๋˜๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.

@keyframes rotate {
  to {
    --angle: 360deg; /* ๋ฌธ์ž์—ด์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณด๊ฐ„ ๋ถˆ๊ฐ€ */
  }
}

ํ•˜์ง€๋งŒ @property๋กœ ํƒ€์ž…์„ ๋“ฑ๋กํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•ด๋‹น ๊ฐ’์„ ์ธ์‹ํ•ด ๋ณด๊ฐ„ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๋ฒ„ํŠผ ํ…Œ๋‘๋ฆฌ์— ๊ทธ๋ผ๋””์–ธํŠธ๊ฐ€ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ํ๋ฅด๋Š” ํšจ๊ณผ๋ฅผ @property๋ฅผ ํ™œ์šฉํ•ด ์ ์šฉํ•ด๋ณด์•˜๋‹ค. conic-gradient์˜ from ๊ฐ๋„์— --angle์„ ์—ฐ๊ฒฐํ•˜๊ณ , ์ด ๊ฐ’์„ @property๋กœ ํƒ€์ž…์œผ๋กœ ๋“ฑ๋กํ•ด ์• ๋‹ˆ๋ฉ”์ด์…˜ ํ•˜๋ฉด ๊ทธ๋ผ๋””์–ธํŠธ์˜ ์ง„ํ–‰ ๋ฐฉํ–ฅ๋งŒ ํšŒ์ „ํ•˜๊ฒŒ ๋œ๋‹ค. ํ•ด๋‹น ๋ฐฉ๋ฒ•์œผ๋กœ ํ…Œ๋‘๋ฆฌ๊ฐ€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํ๋ฅด๋Š” ํšจ๊ณผ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์—ˆ๋‹ค. (๋ฌธ๋ฒ•์€ Tailwind๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ–ˆ๋‹ค.)

@property --angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

.btn-border {
  background:
    linear-gradient(white, white) padding-box,
     conic-gradient(
          from var(--angle),
          var(--color-green-500, #dddd07),
          var(--color-blue-400, #4a9df7),
          var(--color-pink-500, #e361af)
        ) border-box;
  border: 4px solid transparent;
  animation: spin 3s linear infinite;
}

@keyframes spin {
  to { --angle: 360deg; }
}