Sass์ ๊ฐ์ ์ ์ฒ๋ฆฌ๊ธฐ๋ถํฐ ๋ค์ดํฐ๋ธ CSS๊น์ง CSS ๋ฏน์ค์ธ ์ ์ฉ๋ฒ์ ํ๊ตฌํ๊ณ , ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ, ์ ์ง๋ณด์์ฑ, ํจ์จ์ ์ธ ์คํ์ผ๋ง์ ์ํ ๊ธ๋ก๋ฒ ์น ๊ฐ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ง์คํฐํ์ธ์.
CSS Apply ๊ท์น ๋ง์คํฐํ๊ธฐ: ๊ธ๋ก๋ฒ ์น ๊ฐ๋ฐ์ ์ํ ๋ฏน์ค์ธ(Mixin) ์ ์ฉ ์ข ํฉ ๊ฐ์ด๋
๋์์์ด ํ์ฅํ๊ณ ์งํํ๋ ์น ๊ฐ๋ฐ ํ๊ฒฝ์์ ํจ์จ์ฑ, ์ ์ง๋ณด์์ฑ, ํ์ฅ์ฑ์ ๊ฐ์ฅ ์ค์ํฉ๋๋ค. CSS ์คํ์ผ์ํธ๊ฐ ๋ณต์กํด์ง์ ๋ฐ๋ผ, ๋ฐ๋ณต์ ์ธ ์ฝ๋๋ฅผ ๊ด๋ฆฌํ๊ณ ๋ค์ํ ์น ํ๋ก์ ํธ์์ ์ผ๊ด์ฑ์ ๋ณด์ฅํ๋ ๊ฒ์ ์ค์ํ ๊ณผ์ ๊ฐ ๋ฉ๋๋ค. ๋ฐ๋ก ์ด ์ง์ ์์ '๋ฏน์ค์ธ(mixins)'์ด๋ผ๋ ๊ฐ๋ ์ด ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ๊ณผ ๊ฐ์ํ๋ ๊ฐ๋ฐ ์ํฌํ๋ก์ฐ๋ฅผ ์ํ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ๋ฉฐ ๊ฐ๋ ฅํ ํด๊ฒฐ์ฑ ์ผ๋ก ๋ถ์ํฉ๋๋ค.
์ด ์ข
ํฉ ๊ฐ์ด๋์์๋ CSS ๋ฏน์ค์ธ ์ ์ฉ์ ์ธ๊ณ๋ฅผ ๊น์ด ํ๊ณ ๋ค์ด, ๊ทธ ๊ธฐ๋ณธ ์์น, ์ธ๊ธฐ ์๋ CSS ์ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ฌ์ฉํ ์ค์ ๊ตฌํ, ๊ทธ๋ฆฌ๊ณ ๋ค์ดํฐ๋ธ CSS @apply
๊ท์น์ ์ญ์ฌ์ ๋งฅ๋ฝ์ ํ๊ตฌํฉ๋๋ค. ์ฐ๋ฆฌ๋ ๋ฏน์ค์ธ์ด ์ด๋ป๊ฒ ๊ฐ๋ฐ์๋ค์ด ๋ ๊นจ๋ํ๊ณ , ๋ ์ฒด๊ณ์ ์ด๋ฉฐ, ์ฝ๊ฒ ์ ์ง๋ณด์ํ ์ ์๋ CSS๋ฅผ ์์ฑํ๋๋ก ๋๋์ง ๋ถ์ํ ๊ฒ์
๋๋ค. ์ด๋ ์๋ก ๋ค๋ฅธ ์๊ฐ๋์ ๋ฌธํ์ ๋ฐฐ๊ฒฝ์ ๊ฐ์ง ํ๋ค์ด ํ์
ํ์ฌ ์ ์ธ๊ณ์ ์ผ๋ก ์ผ๊ด๋ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ณด์ฅํ๋ ๋ฐ ์์ด ๋งค์ฐ ์ค์ํ ์ธก๋ฉด์
๋๋ค.
CSS ๊ฐ๋ฐ์์ ๋ฏน์ค์ธ์ ํต์ฌ ๊ฐ๋
๋ณธ์ง์ ์ผ๋ก ๋ฏน์ค์ธ์ ์คํ์ผ์ํธ ์ ์ฒด์์ ์ฌ์ฌ์ฉํ ์ ์๋ CSS ์ ์ธ ๋ธ๋ก์ ๋๋ค. ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ํจ์์ ๊ฐ๋ค๊ณ ์๊ฐํ ์ ์์ง๋ง, CSS๋ฅผ ์ํ ๊ฒ์ ๋๋ค. ๋ค์ํ ์์์ ๋ํด ๋์ผํ ์์ฑ ์งํฉ์ ๋ฐ๋ณต์ ์ผ๋ก ์ ์ํ๋ ๋์ , ๋ฏน์ค์ธ ๋ด์์ ํ ๋ฒ ์ ์ํ ๋ค์ ํด๋น ์์ฑ์ด ํ์ํ ๊ณณ๋ง๋ค ๊ทธ ๋ฏน์ค์ธ์ ๊ฐ๋จํ 'ํฌํจ(include)'ํ๊ฑฐ๋ '์ ์ฉ(apply)'ํ๋ฉด ๋ฉ๋๋ค. ์ด๋ฌํ ๋ฐ๋ณตํ์ง ๋ง๋ผ(Don't Repeat Yourself, DRY) ์์น์ ์ค์๋ ํ๋์ ์ด๊ณ ํจ์จ์ ์ธ ์น ๊ฐ๋ฐ์ ๊ธฐ๋ณธ์ ๋๋ค.
๋ฏน์ค์ธ์ ์ฑํํ๋ ์ฃผ๋ ๋๊ธฐ๋ ๋ช ํํฉ๋๋ค:
-
ํฅ์๋ ์ฌ์ฌ์ฉ์ฑ: ๊ณตํต ์คํ์ผ์ ํ ๋ฒ ์ ์ํ๊ณ ๋ชจ๋ ๊ณณ์ ์ ์ฉํ์ฌ ์ค๋ณต์ ์ค์ ๋๋ค.
-
๊ฐ์ ๋ ์ ์ง๋ณด์์ฑ: ์คํ์ผ ๋ธ๋ก์ ๋ณ๊ฒฝ์ ์ค์ง ํ ๊ณณ, ์ฆ ๋ฏน์ค์ธ ์ ์์์๋ง ์ด๋ฃจ์ด์ง๋ฉด ๋๋ฉฐ, ๋ณ๊ฒฝ ์ฌํญ์ ๋ฏน์ค์ธ์ด ์ฌ์ฉ๋ ๋ชจ๋ ๊ณณ์ ์๋์ผ๋ก ์ ํ๋ฉ๋๋ค. ์ด๋ ์ฅ๊ธฐ ํ๋ก์ ํธ์ ๋๊ท๋ชจ ํ์๊ฒ ๋งค์ฐ ์ค์ํฉ๋๋ค.
-
๋์ ์ผ๊ด์ฑ: ๋ฒํผ ์คํ์ผ, ํ์ดํฌ๊ทธ๋ํผ ์ค์ผ์ผ, ๋ ์ด์์ ๊ตฌ์ฑ๊ณผ ๊ฐ์ด ์์ฃผ ์ฌ์ฉ๋๋ ๋์์ธ ํจํด์ ํ์คํํ์ฌ ์น์ฌ์ดํธ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ ๊ฑธ์ณ ํต์ผ๋ ๋ชจ์๊ณผ ๋๋์ ๋ณด์ฅํฉ๋๋ค.
-
ํ์ผ ํฌ๊ธฐ ๊ฐ์(์ปดํ์ผ ํ): ์ ์ฒ๋ฆฌ๊ธฐ ์์ค ํ์ผ์๋ ๋ฏน์ค์ธ ์ ์๊ฐ ํฌํจ๋ ์ ์์ง๋ง, ์ปดํ์ผ๋ CSS๋ ์ข ์ข ๋ ๋์ ๊ตฌ์ฑ์ ํตํด ์ด์ ์ ์ป์ต๋๋ค. ๋ค๋ง ์ต์ข ํ์ผ ํฌ๊ธฐ๋ ๋ฏน์ค์ธ์ด ๋ช ๋ฒ ํฌํจ๋์๋์ง์ ์ผ๋ง๋ ํจ์จ์ ์ผ๋ก ์์ฑ๋์๋์ง์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค.
-
๊ฐ๋ฐ ๊ฐ์ํ: ๋ฏธ๋ฆฌ ์ ์๋ ์คํ์ผ ๋ธ๋ก์ ์ฌ์ฉํ์ฌ ๊ฐ๋ฐ์๋ ๋ฐ๋ณต์ ์ธ ์คํ์ผ๋ง ์์ ๋ณด๋ค๋ ๊ณ ์ ํ ์ธก๋ฉด์ ์ง์คํ๋ฉด์ ์ปดํฌ๋ํธ์ ํ์ด์ง๋ฅผ ํจ์ฌ ๋น ๋ฅด๊ฒ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
์ญ์ฌ์ ์ผ๋ก ์์ CSS์์ ์ด ์์ค์ ์ฌ์ฌ์ฉ์ฑ์ ๋ฌ์ฑํ๋ ๊ฒ์ ์ด๋ ค์ ์ต๋๋ค. ๊ฐ๋ฐ์๋ค์ ์ข ์ข ์ ํธ๋ฆฌํฐ ํด๋์ค๋ ๋ณต์กํ ์ ํ์ ์ฒด์ธ์ ์์กดํ์ผ๋ฉฐ, ์ด๋ ์ฅํฉํ HTML์ด๋ ๊ด๋ฆฌํ๊ธฐ ์ด๋ ค์ด ์คํ์ผ์ํธ๋ก ์ด์ด์ง ์ ์์์ต๋๋ค. CSS ์ ์ฒ๋ฆฌ๊ธฐ์ ๋ฑ์ฅ์ ์ด๋ฅผ ํ์ ํ์ผ๋ฉฐ, ์ต๊ทผ์๋ ์ฌ์ฉ์ ์ง์ ์์ฑ(Custom Properties)๊ณผ ๊ฐ์ ๋ค์ดํฐ๋ธ CSS ๊ธฐ๋ฅ์ด ๋ฐ๋ณต์ ์ธ ์คํ์ผ์ ๊ด๋ฆฌํ๋ ์๋ก์ด ๊ธธ์ ์ ์ํ๊ณ ์์ต๋๋ค.
CSS ์ ์ฒ๋ฆฌ๊ธฐ์์์ ๋ฏน์ค์ธ: ์ฌ์ฌ์ฉ์ฑ์ ์ฃผ์ญ
Sass(Syntactically Awesome Style Sheets), Less, Stylus์ ๊ฐ์ CSS ์ ์ฒ๋ฆฌ๊ธฐ๋ ์ค๋ซ๋์ ๋ณ์, ํจ์, ๊ทธ๋ฆฌ๊ณ ๊ฒฐ์ ์ ์ผ๋ก ๋ฏน์ค์ธ์ ํฌํจํ ํ๋ก๊ทธ๋๋ฐ๊ณผ ์ ์ฌํ ๊ธฐ๋ฅ์ผ๋ก CSS๋ฅผ ํ์ฅํ๋ ๋ฐ ์ฌ์ฉ๋์ด ์จ ๋๊ตฌ์ ๋๋ค. ๋ฌธ๋ฒ์ ๋ค๋ฅด์ง๋ง, ๋ฏน์ค์ธ์ ๋ํ ๊ธฐ๋ณธ ์ฒ ํ์ ๋งค์ฐ ์ ์ฌํฉ๋๋ค: ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์คํ์ผ ๋ธ๋ก์ ์ ์ํ ๋ค์ ์ด๋ฅผ ํฌํจ์ํค๋ ๊ฒ์ ๋๋ค.
Sass ๋ฏน์ค์ธ: ์ ์ฉ์ ๋ํ ์ฌ์ธต ๋ถ์
๊ฐ์ฅ ์ธ๊ธฐ ์๊ณ ๊ธฐ๋ฅ์ด ํ๋ถํ ์ ์ฒ๋ฆฌ๊ธฐ ์ค ํ๋์ธ Sass๋ ๊ฐ๋ ฅํ ๋ฏน์ค์ธ ์์คํ ์ ์ ๊ณตํฉ๋๋ค. ์ธ์, ๊ธฐ๋ณธ๊ฐ, ์ฝํ ์ธ ๋ธ๋ก์ ํตํด ์ ์ฐ์ฑ์ ์ ๊ณตํ์ฌ ๋ค์ํ ์ฌ์ฉ ์ฌ๋ก์ ๋งค์ฐ ๊ฐ๋ ฅํฉ๋๋ค.
๊ธฐ๋ณธ ๋ฏน์ค์ธ ์ ์ํ๊ธฐ
Sass์์ ๋ฏน์ค์ธ์ @mixin
์ง์์ด์ ์ด๋ฆ์ ์ฌ์ฉํ์ฌ ์ ์๋ฉ๋๋ค. ์ด ์ด๋ฆ์ ๋ช
ํ์ฑ์ ์ํด ์ผ๋ฐ์ ์ผ๋ก ์ผ๋ฐฅ ์ผ์ด์ค(kebab-case)๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์์: ๊ธฐ๋ณธ ์ค์ ์ ๋ ฌ ๋ฏน์ค์ธ
@mixin center-element {
display: flex;
justify-content: center;
align-items: center;
}
์ด ๊ฐ๋จํ ๋ฏน์ค์ธ์ Flexbox๋ฅผ ์ฌ์ฉํ์ฌ ์์๋ฅผ ์ค์์ ๋ฐฐ์นํ๋ ๋ฐ ํ์ํ ๊ณตํต ์์ฑ์ ์บก์ํํฉ๋๋ค. ๋ฏน์ค์ธ์ด ์๋ค๋ฉด ๋ฌด์ธ๊ฐ๋ฅผ ์ค์์ ๋ฐฐ์นํ ๋๋ง๋ค ์ด ์ธ ์ค์ ๋ฐ๋ณตํด์ผ ํ ๊ฒ์ ๋๋ค.
๋ฏน์ค์ธ ํฌํจํ๊ธฐ
์ ์๋ ๋ฏน์ค์ธ์ ์ฌ์ฉํ๋ ค๋ฉด CSS ๊ท์น ๋ด์์ @include
์ง์์ด๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ปดํ์ผ๋ ๋ ์ ์ฒ๋ฆฌ๊ธฐ๋ @include
ํธ์ถ์ ๋ฏน์ค์ธ์ ์ค์ CSS ์ ์ธ์ผ๋ก ๋์ฒดํฉ๋๋ค.
์์: ์ค์ ์ ๋ ฌ ๋ฏน์ค์ธ ํฌํจํ๊ธฐ
.card {
width: 300px;
height: 200px;
background-color: #f0f0f0;
@include center-element;
}
.modal {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
@include center-element;
}
์ปดํ์ผ ์ .card
ํด๋์ค์ ๋ํ CSS ์ถ๋ ฅ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
.card {
width: 300px;
height: 200px;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
}
์ด๋ ๋ฏน์ค์ธ์ ๊ทผ๋ณธ์ ์ธ ํ์ ๋ณด์ฌ์ค๋๋ค: ์์ฑํ ์ค์ด ์ค์ด๋ค๊ณ ๊ด๋ฆฌํ๊ธฐ๊ฐ ๋ ์ฌ์์ง๋๋ค.
์ธ์๊ฐ ์๋ ๋ฏน์ค์ธ: ๋์ ์คํ์ผ๋ง
๋ฏน์ค์ธ์ ์ง์ ํ ํ์ ๋์ ๊ฐ์ ๋ฐ์๋ค์ผ ์ ์๋ ์ธ์๋ฅผ ๋์ ํ ๋ ๋ํ๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ๋งค์ฐ ์ ์ฐํ๊ณ ์ ์์ฑ ๋์ ์คํ์ผ ๋ธ๋ก์ ์์ฑํ ์ ์์ต๋๋ค.
์์น ๊ธฐ๋ฐ ์ธ์
์ธ์๋ ํจ์ ๋งค๊ฐ๋ณ์์ ์ ์ฌํ๊ฒ ๋ฏน์ค์ธ ์ด๋ฆ ๋ค์ ๊ดํธ ์์ ์ ์๋ฉ๋๋ค. ๋ฏน์ค์ธ์ ํฌํจํ ๋ ๋์ผํ ์์๋ก ๊ฐ์ ์ ๋ฌํฉ๋๋ค.
์์: ๋์ ๋ฒํผ ์คํ์ผ
@mixin button-styles($bg-color, $text-color, $padding) {
display: inline-block;
padding: $padding;
background-color: $bg-color;
color: $text-color;
border: none;
border-radius: 5px;
cursor: pointer;
text-decoration: none;
font-weight: bold;
}
.btn-primary {
@include button-styles(#007bff, #fff, 10px 20px);
}
.btn-secondary {
@include button-styles(#6c757d, #fff, 8px 16px);
}
์ด ๋ฏน์ ์ ์ด์ ๋ฐฐ๊ฒฝ์, ํ ์คํธ ์์, ํจ๋ฉ์ ๋ํด ๋ค๋ฅธ ์ธ์๋ฅผ ์ ๊ณตํ๋ ๊ฒ๋ง์ผ๋ก ๋ค์ํ ๋ฒํผ ์คํ์ผ์ ์์ฑํ ์ ์๊ฒ ํ์ฌ ๋ฐ๋ณต์ ์ธ ์ฝ๋๋ฅผ ๊ทน์ ์ผ๋ก ์ค์ฌ์ค๋๋ค.
ํค์๋ ์ธ์ ๋ฐ ๊ธฐ๋ณธ๊ฐ
Sass๋ ๋ํ ํค์๋ ์ธ์๋ฅผ ์ง์ํ์ฌ ์ด๋ฆ์ผ๋ก ๊ฐ์ ์ ๋ฌํ ์ ์๊ฒ ํจ์ผ๋ก์จ ๊ฐ๋ ์ฑ์ ํฅ์์ํต๋๋ค. ์ด๋ ํนํ ์ธ์๊ฐ ๋ง์ ๋ฏน์ค์ธ์ ์ ์ฉํฉ๋๋ค. ์ธ์์ ๊ธฐ๋ณธ๊ฐ์ ํ ๋นํ์ฌ ๋ฏน์ค์ธ์ ํฌํจํ ๋ ์ ํ์ ์ผ๋ก ๋ง๋ค ์๋ ์์ต๋๋ค.
์์: ๊ธฐ๋ณธ๊ฐ์ด ์๋ ๋ฐ์ํ ํ์ดํฌ๊ทธ๋ํผ ๋ฏน์ค์ธ
@mixin responsive-text($font-size, $line-height: 1.5, $color: #333) {
font-size: $font-size;
line-height: $line-height;
color: $color;
}
.hero-heading {
@include responsive-text(48px, 1.2, #1a1a1a);
}
.body-text {
@include responsive-text(16px);
/* line-height๋ 1.5, color๋ #333์ด ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฌ์ฉ๋จ */
}
.caption {
@include responsive-text($font-size: 14px, $color: #777);
/* line-height๋ 1.5๊ฐ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฌ์ฉ๋จ */
}
๊ธฐ๋ณธ๊ฐ์ ํฉ๋ฆฌ์ ์ธ ๋์ฒด ๊ฐ์ ์ ๊ณตํ๊ณ ์ผ๋ฐ์ ์ธ ์๋๋ฆฌ์ค์์ ์ ๋ฌํด์ผ ํ๋ ์ธ์์ ์๋ฅผ ์ค์ด๋ ๋ฐ ๋งค์ฐ ์ ์ฉํฉ๋๋ค. ํค์๋ ์ธ์๋ ํนํ ์ธ์์ ์์๊ฐ ์ฆ์ ๋ช ํํ์ง ์์ ๋ ๋ช ํ์ฑ์ ํฅ์์ํต๋๋ค.
๊ฐ๋ณ ๊ฐ์ ์
๋ ฅ์ ์ํ ๋๋จธ์ง ์ธ์(...
)
๋ฏน์ค์ธ์ด ์์์ ์์ ์ธ์๋ฅผ ๋ฐ์์ผ ํ๋ ์๋๋ฆฌ์ค๋ฅผ ์ํด Sass๋ ...
๋ฅผ ์ฌ์ฉํ๋ ๋๋จธ์ง ์ธ์๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด๋ box-shadow
๋ text-shadow
์ ๊ฐ์ด ์ฌ๋ฌ ๊ฐ์ ๋ฐ๋ ์์ฑ์ ํนํ ์ ์ฉํฉ๋๋ค.
์์: ์ ์ฐํ ๊ทธ๋ฆผ์ ๋ฏน์ค์ธ
@mixin multi-shadow($shadows...) {
box-shadow: $shadows;
}
.element-with-shadow {
@include multi-shadow(0 2px 4px rgba(0,0,0,0.1), 0 8px 16px rgba(0,0,0,0.2));
}
.another-element {
@include multi-shadow(inset 0 0 10px red);
}
์ด ๋ฏน์ค์ธ์ ์ ๋ฌ๋ ๋ชจ๋ ์์ ๊ทธ๋ฆผ์ ์ ์๋ฅผ ์ ์ฐํ๊ฒ ์ฒ๋ฆฌํ์ฌ box-shadow
์์ฑ์ผ๋ก ์ง์ ์ปดํ์ผํฉ๋๋ค.
์ฝํ ์ธ ๊ฐ ์๋ ๋ฏน์ค์ธ: ์คํ์ผ ๋ธ๋ก ์ ๋ฌํ๊ธฐ
Sass์ @content
์ง์์ด๋ CSS ๊ท์น์ด๋ ์ ์ธ ๋ธ๋ก์ ๋ฏน์ค์ธ์ ์ง์ ์ ๋ฌํ ์ ์๊ฒ ํด์ฃผ๋ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์
๋๋ค. ์ด๋ ํน์ ์คํ์ผ์ด ์ ์ฉ๋์ด์ผ ํ๋ ๋ํผ๋ ํน์ ์ปจํ
์คํธ๋ฅผ ๋ง๋๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค.
์์: ์ฝํ ์ธ ๊ฐ ์๋ ๋ฏธ๋์ด ์ฟผ๋ฆฌ ๋ฏน์ค์ธ
@mixin breakpoint($point) {
@if $point == desktop {
@media (min-width: 1024px) {
@content;
}
} @else if $point == tablet {
@media (min-width: 768px) and (max-width: 1023px) {
@content;
}
} @else if $point == mobile {
@media (max-width: 767px) {
@content;
}
}
}
.my-component {
width: 100%; /* ๊ธฐ๋ณธ ๋ชจ๋ฐ์ผ ์ฐ์ */
@include breakpoint(tablet) {
width: 75%;
margin: 0 auto;
}
@include breakpoint(desktop) {
width: 50%;
max-width: 960px;
margin: 0 auto;
}
}
์ด ์์์ @mixin breakpoint
๋ด์ @content
์ง์์ด๋ ์ปดํฌ๋ํธ์ ๊ท์น ์งํฉ ๋ด์์ ์ง์ ๋ค๋ฅธ ํ๋ฉด ํฌ๊ธฐ์ ๋ํ ํน์ ์คํ์ผ์ ์ ์ํ ์ ์๊ฒ ํ์ฌ ๋ฏธ๋์ด ์ฟผ๋ฆฌ๋ฅผ ๊ด๋ จ ์ปดํฌ๋ํธ์ ๊ตญํ์ํต๋๋ค. ์ด ํจํด์ ๋ฐ์ํ ๋์์ธ์ ๊ด๋ฆฌํ๊ณ ์คํ์ผ์ํธ์ ๊ฐ๋
์ฑ์ ํฅ์์ํค๋ ๋ฐ ๋งค์ฐ ์ธ๊ธฐ๊ฐ ์์ผ๋ฉฐ, ํนํ ๊ธ๋ก๋ฒ ํ์์ ๋๋ฆฌ ํผ์ ธ ์๋ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ์ํคํ
์ฒ์์ ์ ์ฉํฉ๋๋ค.
๊ณ ๊ธ ๋ฏน์ค์ธ ํจํด ๋ฐ ๊ณ ๋ ค ์ฌํญ
๋ฏน์ค์ธ์ ๋ค๋ฅธ Sass ๊ธฐ๋ฅ๊ณผ ๊ฒฐํฉํ์ฌ ๋์ฑ ์ ๊ตํ๊ณ ๋์ ์ธ ์คํ์ผ์ ๋ง๋ค ์ ์์ต๋๋ค.
๋ฏน์ค์ธ ๋ด์ ์กฐ๊ฑด๋ถ ๋ก์ง
๋ฏน์ค์ธ ๋ด์์ @if
, @else if
, @else
์ง์์ด๋ฅผ ์ฌ์ฉํ์ฌ ์กฐ๊ฑด์ ๋ฐ๋ผ ์คํ์ผ์ ์ ์ฉํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๊ณ ๋๋ก ๊ตฌ์ฑ ๊ฐ๋ฅํ ๋ฏน์ค์ธ์ ๋ง๋ค ์ ์์ต๋๋ค.
์์: ํ ๋ง๋ฅผ ์ธ์ํ๋ ๋ฒํผ ๋ฏน์ค์ธ
@mixin themed-button($theme: default) {
@if $theme == default {
background-color: #007bff;
color: #fff;
} @else if $theme == dark {
background-color: #343a40;
color: #fff;
} @else if $theme == light {
background-color: #f8f9fa;
color: #333;
border: 1px solid #ddd;
} @else {
@warn "Unknown theme #{$theme} used in themed-button mixin.";
background-color: #ccc;
color: #000;
}
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
}
.btn-buy {
@include themed-button(dark);
}
.btn-checkout {
@include themed-button(light);
}
์ด ๋ฏน์ค์ธ์ ์ง์ ๋ ํ ๋ง์ ๋ฐ๋ผ ๋ค๋ฅธ ๋ฒํผ ์คํ์ผ์ ์ ๊ณตํ์ฌ ์๊ฐ์ ๋ณํ์ ์ผ๊ด๋๊ฒ ๊ด๋ฆฌํ๋ ๊ฐ๋ ฅํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
๋ฏน์ค์ธ์์์ ๋ฃจํ
Sass ๋ฃจํ(@for
, @each
, @while
)๋ ๋ฏน์ค์ธ์ ํตํฉ๋์ด ๊ฐ๊ฒฉ ์ ํธ๋ฆฌํฐ๋ ์ปฌ๋ผ ๊ทธ๋ฆฌ๋์ ๊ฐ์ ๋ฐ๋ณต์ ์ธ ์คํ์ผ์ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ์์ฑํ ์ ์์ต๋๋ค.
์์: ๋ฃจํ๋ฅผ ์ด์ฉํ ๊ฐ๊ฒฉ ์ ํธ๋ฆฌํฐ ๋ฏน์ค์ธ
@mixin generate-spacing-utilities($max: 5, $step: 5px) {
@for $i from 1 through $max {
$value: $i * $step;
.margin-#{$i} {
margin: $value;
}
.padding-#{$i} {
padding: $value;
}
}
}
@include generate-spacing-utilities(5, 10px);
/* ์ด๋ .margin-1 { margin: 10px; }๋ถํฐ .margin-5 { margin: 50px; }๊น์ง์ ํด๋์ค๋ฅผ ์์ฑํฉ๋๋ค. */
์ด ๋ฏน์ค์ธ์ ์ผ๊ด๋ ๊ฐ๊ฒฉ์ ์ํ ์ ํธ๋ฆฌํฐ ํด๋์ค ์งํฉ์ ์์ฑํ์ฌ ์๋นํ ์์์ ์ ์ ์ฝํ๊ณ ํต์ผ๋ ๋์์ธ ์์คํ ์ ๋ณด์ฅํฉ๋๋ค. ์ด๋ฌํ ์ ํธ๋ฆฌํฐ ํด๋์ค๋ ๊ฐ๋ฐ์๋ค์ด ํ์คํ๋ ๊ฐ๊ฒฉ ๊ฐ์ ๋น ๋ฅด๊ฒ ์ ๊ทผํด์ผ ํ๋ ๋๊ท๋ชจ ๊ธ๋ก๋ฒ ๋ถ์ฐ ํ๋ก์ ํธ์์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
๋ฏน์ค์ธ vs. ํจ์ vs. ํ๋ ์ด์คํ๋(%extend
)
Sass๋ ๋ฏน์ค์ธ๊ณผ ์ ์ฌํด ๋ณด์ด์ง๋ง ๋๋ ทํ ๋ชฉ์ ์ ๊ฐ์ง ๋ค๋ฅธ ๊ธฐ๋ฅ๋ค์ ์ ๊ณตํฉ๋๋ค:
-
ํจ์: Sass ํจ์(
@function
์ผ๋ก ์ ์)๋ ๋จ์ผ ๊ฐ์ ๊ณ์ฐํ๊ณ ๋ฐํํฉ๋๋ค. ๊ณ์ฐ, ์์ ์กฐ์ ๋๋ ๋ฌธ์์ด ์ฐ์ฐ์ ์ฌ์ฉ๋ฉ๋๋ค. ์ง์ CSS๋ฅผ ์ถ๋ ฅํ์ง ์์ต๋๋ค. ๋ฐ๋ฉด์ ๋ฏน์ค์ธ์ CSS ์์ฑ์ ์ถ๋ ฅํฉ๋๋ค.์์: ํจ์ vs. ๋ฏน์ค์ธ
@function px-to-rem($px) { @return $px / 16px * 1rem; /* ํจ์๋ ๊ณ์ฐ๋ ๊ฐ์ ๋ฐํํฉ๋๋ค */ } .element { font-size: px-to-rem(24px); } @mixin custom-heading($font-size) { font-size: $font-size; /* ๋ฏน์ค์ธ์ CSS๋ฅผ ์ถ๋ ฅํฉ๋๋ค */ font-weight: bold; } .page-title { @include custom-heading(px-to-rem(32px)); }
-
ํ๋ ์ด์คํ๋(
%extend
): ํ๋ ์ด์คํ๋ ์ ํ์(์:%button-base
)๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์คํ์ผ ๋ธ๋ก์ ํฌํจํ๋ค๋ ์ ์์ ๋ฏน์ค์ธ๊ณผ ์ ์ฌํ์ง๋ง,@extend
์ง์์ด๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฅ๋๋๋ก ์ค๊ณ๋์์ต๋๋ค. ํฌํจ๋ ๋๋ง๋ค CSS ์ ์ธ์ ๋ณต์ ํ๋ ๋ฏน์ค์ธ๊ณผ ๋ฌ๋ฆฌ,@extend
๋ ์ ํ์๋ฅผ ์ง๋ฅ์ ์ผ๋ก ๊ทธ๋ฃนํํ์ฌ ์ค๋ณต์ ๋ฐฉ์งํจ์ผ๋ก์จ ์ ์ฌ์ ์ผ๋ก ๋ ์์ ์ปดํ์ผ๋ CSS๋ฅผ ๋ง๋ญ๋๋ค. ๊ทธ๋ฌ๋@extend
๋ ๋ถ์ ์ ํ๊ฒ ์ฌ์ฉ๋ ๊ฒฝ์ฐ, ํนํ ๋ณต์กํ ์ค์ฒฉ ์ ํ์์ ํจ๊ป ์ฌ์ฉ๋ ๋ ์๊ธฐ์น ์์ ์ ํ์ ์ถ๋ ฅ์ด๋ ๋ ํฐ ํ์ผ ํฌ๊ธฐ๋ฅผ ์ด๋ํ ์ ์์ต๋๋ค. ๋ฏน์ค์ธ์ ์ผ๋ฐ์ ์ผ๋ก ๊ณ ์ ํ ์์ฑ ๋ธ๋ก์ ํฌํจํ๋ ๋ฐ ์ ํธ๋๋ฉฐ,@extend
๋ ๊ด๋ จ ์ปดํฌ๋ํธ ๊ฐ์ ๊ณตํต ๊ธฐ๋ณธ ์คํ์ผ์ ๊ณต์ ํ๋ ๋ฐ ๋ ์ ํฉํฉ๋๋ค.์์: ๋ฏน์ค์ธ vs. Extend
@mixin alert-style { padding: 15px; margin-bottom: 20px; border: 1px solid transparent; border-radius: 4px; } %message-base { padding: 15px; margin-bottom: 20px; border: 1px solid transparent; border-radius: 4px; } .alert-success { @include alert-style; background-color: #d4edda; color: #155724; } .message-error { @extend %message-base; background-color: #f8d7da; color: #721c24; }
.alert-success
์ ์ปดํ์ผ๋ ์ถ๋ ฅ์alert-style
์์ฑ์ ๋ณต์ ํฉ๋๋ค..message-error
์ ๊ฒฝ์ฐ,%message-base
์์ฑ์.message-error
์ ํ์์ ๊ทธ๋ฃนํ๋ฉ๋๋ค./* ๋ฏน์ค์ธ์ ์ปดํ์ผ๋ ์ถ๋ ฅ */ .alert-success { padding: 15px; margin-bottom: 20px; border: 1px solid transparent; border-radius: 4px; background-color: #d4edda; color: #155724; } /* extend์ ์ปดํ์ผ๋ ์ถ๋ ฅ */ .message-error, .some-other-class-that-extends-it { padding: 15px; margin-bottom: 20px; border: 1px solid transparent; border-radius: 4px; } .message-error { background-color: #f8d7da; color: #721c24; }
๋ฏน์ค์ธ๊ณผ
@extend
์ฌ์ด์ ์ ํ์ ์ข ์ข ํน์ ์๋๋ฆฌ์ค์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค: ๋ฏน์ค์ธ์ ๊ณ ์ ํ๊ณ ์ ์ฌ์ ์ผ๋ก ๋งค๊ฐ๋ณ์ํ๋ ์์ฑ ๋ธ๋ก์,@extend
๋ ์ต์ํ์ ์ค๋ณต์ด ์ค์ํ ์ฌ๋ฌ ์ ํ์ ๊ฐ์ ๊ธฐ๋ณธ ๊ท์น ์งํฉ์ ๊ณต์ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
Less์ Stylus์์์ ๋ฏน์ค์ธ
Sass๊ฐ ๋๋ฆฌ ์ฑํ๋์์ง๋ง, Less์ Stylus๋ ์ ์ฌํ ๋ฏน์ค์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค:
-
Less ๋ฏน์ค์ธ: Less์์ ๋ฏน์ค์ธ์ ๋ณธ์ง์ ์ผ๋ก ํธ์ถํ ์ ์๋ CSS ๊ท์น ์งํฉ์ ๋๋ค. ์ผ๋ฐ CSS ํด๋์ค๋ ID์ฒ๋ผ ์ ์๋๋ฉฐ, ๋ค๋ฅธ ๊ท์น ์งํฉ ๋ด์์ ๋จ์ํ ์ด๋ฆ์ ํธ์ถํ์ฌ ํฌํจ๋ฉ๋๋ค. Less ๋ฏน์ค์ธ์ ์ธ์์ ๊ธฐ๋ณธ๊ฐ๋ ๋ฐ์ ์ ์์ต๋๋ค.
์์: Less ๋ฏน์ค์ธ
.border-radius(@radius: 5px) { -webkit-border-radius: @radius; -moz-border-radius: @radius; border-radius: @radius; } #header { .border-radius(10px); } .footer { .border-radius(); /* ๊ธฐ๋ณธ๊ฐ 5px ์ฌ์ฉ */ }
Less์๋ ๋งค๊ฐ๋ณ์ ๋ฏน์ค์ธ(์ธ์๊ฐ ์๋ ๋ฏน์ค์ธ)๊ณผ ๊ฐ๋ ๋ฏน์ค์ธ(
when
ํค์๋๋ฅผ ์ฌ์ฉํ๋ ์กฐ๊ฑด๋ถ ๋ฏน์ค์ธ)๋ ์์ต๋๋ค. -
Stylus ๋ฏน์ค์ธ: Stylus๋ ์๋ง๋ ๊ฐ์ฅ ์ ์ฐํ ๊ตฌ๋ฌธ์ ์ ๊ณตํ์ฌ ๊ดํธ์ ์ฝ๋ก ์ ์ ํ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๊ฒ ํฉ๋๋ค. ๋ฏน์ค์ธ์ ๋จ์ํ ํฌํจ๋ ์ ์๋ ์ฝ๋ ๋ธ๋ก์ ๋๋ค. Stylus๋ ๋ํ ์ธ์, ๊ธฐ๋ณธ๊ฐ ๋ฐ ์ฝํ ์ธ ๋ธ๋ก๊ณผ ์ ์ฌํ ๊ฐ๋ (Sass์ ๊ฐ์ ๋ช ์์ ์ธ
@content
์ง์์ด๊ฐ ์๋ ๋ธ๋ก ์ธ์๋ฅผ ํตํด)์ ์ง์ํฉ๋๋ค.์์: Stylus ๋ฏน์ค์ธ
border-radius(radius = 5px) -webkit-border-radius radius -moz-border-radius radius border-radius radius #header border-radius 10px .footer border-radius
Stylus์ ๊ตฌ๋ฌธ ์ ์ฐ์ฑ์ ๋งค์ฐ ๊ฐ๊ฒฐํ ์ฝ๋๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
์ ์ฒ๋ฆฌ๊ธฐ์ ๊ด๊ณ์์ด ํต์ฌ ์ด์ ์ ๋์ผํฉ๋๋ค: ๋ฐ๋ณต์ ์ธ CSS๋ฅผ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋ธ๋ก์ผ๋ก ์ถ์ํํ์ฌ ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ํฌ๊ณ ์งํํ๋ ์คํ์ผ์ํธ ๊ด๋ฆฌ์ ํฌ๊ฒ ๊ธฐ์ฌํฉ๋๋ค.
๋ค์ดํฐ๋ธ CSS @apply
๊ท์น: ์ญ์ฌ์ ๊ด์ ๊ณผ ํ์ฌ ์ํ
์ ์ฒ๋ฆฌ๊ธฐ ๋ฏน์ค์ธ์ ํ๋ก ํธ์๋ ๊ฐ๋ฐ์์ ์ ์ ๋ฆฝ๋๊ณ ํ์์ ์ธ ๋ถ๋ถ์ด์ง๋ง, CSS ์ํน ๊ทธ๋ฃน์ ๋ํ ๋ค์ดํฐ๋ธ CSS์ ์ ์ฌํ ์ฌ์ฌ์ฉ์ฑ์ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์ ๋ชจ์ํ์ต๋๋ค. ์ด๋ CSS ์ฌ์ฉ์ ์ง์ ์์ฑ(CSS ๋ณ์)๊ณผ ํจ๊ป ์๋ํ๋๋ก ์ค๊ณ๋ @apply
๊ท์น์ ์ ์์ผ๋ก ์ด์ด์ก์ต๋๋ค.
์ ์๋์๋ @apply
๊ท์น์ ๋ฌด์์ด์๋๊ฐ?
CSS @apply
๊ท์น์ ์์ฑ์๊ฐ ์ฌ์ฉ์ ์ง์ ์์ฑ ์งํฉ์ ์ ์ํ ๋ค์ ์ด๋ฅผ ์์์ ์ ์ฉํ ์ ์๊ฒ ํ๋ ์คํ์ ์ธ CSS ๊ธฐ๋ฅ์ผ๋ก, ๋ณธ์ง์ ์ผ๋ก ์ฌ์ฉ์ ์ง์ ์์ฑ์ ์ํ ๋ค์ดํฐ๋ธ CSS ๋ฏน์ค์ธ ์ญํ ์ ํ์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ ํํ์์ต๋๋ค:
์์: ์ ์๋์๋ ๋ค์ดํฐ๋ธ @apply
(์ฌ์ฉ ์ค๋จ๋จ)
:root {
--brand-button-theme: {
background-color: #007bff;
color: #fff;
padding: 10px 20px;
border-radius: 5px;
};
}
.my-button {
@apply --brand-button-theme;
font-weight: bold;
text-transform: uppercase;
}
์์ด๋์ด๋ ์ค๋๋ ฅ์ด ์์์ต๋๋ค: ์ฌ์ฉ์ ์ง์ ์์ฑ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ์ด๋ฆ์ด ์ง์ ๋ ์์ฑ ์งํฉ('๋ฏน์ค์ธ' ๋๋ '์์ฑ ์งํฉ')์ ์ ์ํ ๋ค์ @apply
๋ฅผ ์ฌ์ฉํ์ฌ ํฌํจํ๋ ๊ฒ์
๋๋ค. ์ด๋ ์ ์ฒ๋ฆฌ๊ธฐ ์์ด CSS ์ ์ธ ๋ฌถ์์ ๊ด๋ฆฌํ๋ ๋ค์ดํฐ๋ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ ๊ฒ์
๋๋ค.
์ ์ ์๋์๊ณ ์ ์ฌ์ฉ ์ค๋จ๋์๋๊ฐ
@apply
์ ๋๊ธฐ๋ ๋ช
ํํ์ต๋๋ค: ๋์ผํ CSS ์ ์ธ ๋ธ๋ก์ ๋ฐ๋ณตํ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ด์์ต๋๋ค. CSS ์ฌ์ฉ์ ์ง์ ์์ฑ(์: --main-color: blue; color: var(--main-color);
)์ *๊ฐ*์ ์ฌ์ฌ์ฉํ ์ ์๊ฒ ํ์ง๋ง, ๊ทธ ์์ฒด๋ก๋ *์์ฑ ๊ทธ๋ฃน*์ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค. @apply
๋ ์ด ๊ฒฉ์ฐจ๋ฅผ ๋ฉ์ฐ๊ธฐ ์ํด CSS '๋ถ๋ถ(partial)' ๋๋ '๋ฏน์ค์ธ' ํํ๋ฅผ ๋ธ๋ผ์ฐ์ ์ ๋ค์ดํฐ๋ธ๋ก ๊ฐ์ ธ์ค๊ธฐ ์ํด ์๋๋์์ต๋๋ค.
๊ทธ๋ฌ๋ @apply
๊ท์น์ ๊ฒฐ๊ตญ ์ฌ์ฉ ์ค๋จ๋๊ณ CSS ์ฌ์์์ ์ ๊ฑฐ๋์์ต๋๋ค. ์ฌ์ฉ ์ค๋จ์ ์ฃผ๋ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
-
๋ณต์ก์ฑ๊ณผ ์ฑ๋ฅ: ๋ธ๋ผ์ฐ์ ์์
@apply
๋ฅผ ํจ์จ์ ์ผ๋ก ๊ตฌํํ๋ ๊ฒ์ด ์์๋ณด๋ค ๋ณต์กํ์ผ๋ฉฐ, ํนํ ์ ์ฉ๋ ์์ฑ ์งํฉ์ ๋ณ๊ฒฝ์ด ์ด๋ป๊ฒ ๊ณ๋จ์์ผ๋ก ์ ์ฉ๋๊ณ ๋ ์ด์์/ํ์ธํธ ์์ ์ ํธ๋ฆฌ๊ฑฐํ๋์ง์ ๋ํ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. -
๋ค๋ฅธ ๊ธฐ๋ฅ๊ณผ์ ์ค๋ณต: ์งํํ๋ CSS ์ฌ์ฉ์ ์ง์ ์์ฑ ์์ฒด์ ๊ธฐ๋ฅ๊ณผ ์๋น ๋ถ๋ถ ์ค๋ณต๋์์ผ๋ฉฐ, ์ฌ์ฉ์ ์ง์ ์์ฑ์ ๊ฐ์ ๊ณผ ์๋ก์ด ๋ค์ดํฐ๋ธ ๊ธฐ๋ฅ์ ํตํด ๋ ๊ฐ๋ ฅํ ํด๊ฒฐ์ฑ ์ด ๋์ฌ ๊ฐ๋ฅ์ฑ์ด ์์์ต๋๋ค.
-
์คํ์ผ ๊ด๋ จ ์ฐ๋ ค: ์ผ๋ถ์์๋ ๊ตฌ๋ฌธ๊ณผ ์๋ฏธ๊ฐ ํฌ๋ฐํ๊ณ , ๋๋ฒ๊ทธํ๊ธฐ ์ด๋ ค์ด ๊ณ๋จ์ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์๋ค๊ณ ๋ณด์์ต๋๋ค.
ํ์ฌ ๋ค์ดํฐ๋ธ CSS @apply
๊ท์น์ ํ์ค์ ์ผ๋ถ๊ฐ ์๋๋ฉฐ ํ๋ก๋์
ํ๊ฒฝ์์ ์ฌ์ฉํด์๋ ์ ๋ฉ๋๋ค. ๋ธ๋ผ์ฐ์ ์ง์์ ๋ฏธ๋ฏธํ์ผ๋ฉฐ ์ด๋ฏธ ์ ๊ฑฐ๋์์ต๋๋ค.
๋ค์ดํฐ๋ธ CSS์ ํ์ฌ ๋์
@apply
๋ ์ฌ๋ผ์ก์ง๋ง, ๋ค์ดํฐ๋ธ CSS๋ ์ฃผ๋ก CSS ์ฌ์ฉ์ ์ง์ ์์ฑ์ ๊ฐ๋ ฅํ ์ฌ์ฉ๊ณผ ์ ๋ต์ ์ธ ์ปดํฌ๋ํธ ์ค๊ณ๋ฅผ ํตํด ์ฌ์ฌ์ฉ์ฑ์ ์ํ ๊ฐ๋ ฅํ ๋์์ ์ ๊ณตํ๋๋ก ์งํํ์ต๋๋ค.
CSS ์ฌ์ฉ์ ์ง์ ์์ฑ(CSS ๋ณ์)
์ฌ์ฉ์ ์ง์ ์์ฑ์ ์ฌ์ฉํ๋ฉด ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฐ์ ์ ์ํ ์ ์์ผ๋ฉฐ, ์ด๋ฅผ ์ฌ๋ฌ CSS ์์ฑ์ ์ ์ฉํ๊ฑฐ๋ ๊ณ์ฐ์ ์ฌ์ฉํ ์๋ ์์ต๋๋ค. ์์ฑ์ ๊ทธ๋ฃนํํ์ง๋ ์์ง๋ง, ๋์์ธ ํ ํฐ ๋ฐ ๊ธ๋ก๋ฒ ํ ๋ง ๋ณ์๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ๋งค์ฐ ํจ๊ณผ์ ์ ๋๋ค.
์์: ์ฌ์ฉ์ ์ง์ ์์ฑ์ผ๋ก ๊ฐ ์ฌ์ฌ์ฉํ๊ธฐ
:root {
--primary-color: #007bff;
--text-color-light: #f8f9fa;
--button-padding: 10px 20px;
--border-radius-default: 5px;
}
.btn-primary {
background-color: var(--primary-color);
color: var(--text-color-light);
padding: var(--button-padding);
border-radius: var(--border-radius-default);
/* ... ๊ธฐํ ์์ฑ ... */
}
.card-header {
background-color: var(--primary-color);
padding: var(--button-padding);
border-radius: var(--border-radius-default) var(--border-radius-default) 0 0;
/* ... */
}
์ด ์ ๊ทผ ๋ฐฉ์์ ๊ฐ์ ํจ๊ณผ์ ์ผ๋ก ์ค์ ์ง์คํํ์ฌ ๋จ์ผ ์ฌ์ฉ์ ์ง์ ์์ฑ์ ์์ ํจ์ผ๋ก์จ ์น์ฌ์ดํธ ์ ์ฒด์ ๊ธฐ๋ณธ ์์์ด๋ ํจ๋ฉ์ ์ฝ๊ฒ ๋ณ๊ฒฝํ ์ ์๊ฒ ํฉ๋๋ค. ์ด๋ ๊ธ๋ก๋ฒ ๋ธ๋๋ฉ ๋ฐ ํ ๋ง ์ค์ ์ ๋งค์ฐ ์ ์ฉํ๋ฉฐ, ๋ค๋ฅธ ์ง์ญ์ ๋์์ธ ์ ํธ๋๋ ๊ณ์ ๋ณ ์บ ํ์ธ์ ์ ์ํ๊ฒ ์ ์ํ ์ ์๊ฒ ํฉ๋๋ค.
์ ํธ๋ฆฌํฐ ํด๋์ค์ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ CSS
์์ฑ์ ๊ทธ๋ฃนํํ๊ธฐ ์ํด ํ์ค ๋ค์ดํฐ๋ธ CSS ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ ํ ์ ํธ๋ฆฌํฐ ํด๋์ค๋ ์ ์ ์๋ ์ปดํฌ๋ํธ ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. Bootstrap, Tailwind CSS์ ๊ฐ์ ํ๋ ์์ํฌ๋ ์ด ํจํด์ ๋ง์ด ํ์ฉํฉ๋๋ค.
์์: ์ฌ์ฌ์ฉ์ฑ์ ์ํ ์ ํธ๋ฆฌํฐ ํด๋์ค
/* CSS */
.flex-center {
display: flex;
justify-content: center;
align-items: center;
}
.btn {
display: inline-block;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
}
.btn-primary {
background-color: blue;
color: white;
}
/* HTML */
์ด๊ฒ์ ์ผ๋ถ ์คํ์ผ๋ง ์ฑ ์์ HTML๋ก ์ด๋์ํค์ง๋ง(๋ ๋ง์ ํด๋์ค๋ฅผ ์ถ๊ฐํจ์ผ๋ก์จ), ์์ CSS์์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์คํ์ผ ๋ธ๋ก์ ๊ด๋ฆฌํ๋ ๋๋ฆฌ ์ธ์ ๋๊ณ ์ฑ๋ฅ์ด ๋ฐ์ด๋ ๋ฐฉ๋ฒ์ ๋๋ค. ์ด๋ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ๊ฐ๋ฐ์ ์ฅ๋ คํ๋ React, Vue, Angular์ ๊ฐ์ ํ๋์ ์ธ ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ ์์ํฌ์ ์ํํ๊ฒ ํตํฉ๋ฉ๋๋ค.
์ฌ๋ฐ๋ฅธ ์ ๊ทผ ๋ฐฉ์ ์ ํํ๊ธฐ: ์ ์ฒ๋ฆฌ๊ธฐ vs. ๋ค์ดํฐ๋ธ CSS
์ ์ฒ๋ฆฌ๊ธฐ์ ๋ค์ดํฐ๋ธ CSS ๊ธฐ๋ฅ ๋ชจ๋์ ๊ฐ์ ์ ๊ณ ๋ คํ ๋, ๋ฏน์ค์ธ๊ณผ ์ ์ฌํ ๊ธฐ๋ฅ์ ์ด๋ค ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ ์ง ๊ฒฐ์ ํ๋ ๊ฒ์ ํ๋ก์ ํธ ์๊ตฌ ์ฌํญ, ํ์ ์น์๋ ๋ฐ ํ์ํ ์คํ์ผ๋ง์ ๋ณต์ก์ฑ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค.
์ ์ฒ๋ฆฌ๊ธฐ ๋ฏน์ค์ธ์ ์ฌ์ฉํด์ผ ํ ๋
-
๋ณต์กํ ๋ก์ง ๋ฐ ๊ณ์ฐ: ์คํ์ผ์ ๊ณ ๊ธ ๋ก์ง(
@if
,@for
,@each
), ๋ณต์กํ ์ํ์ ๊ณ์ฐ ๋๋ ๋์ ์์ฑ ์์ฑ์ด ํ์ํ ๊ฒฝ์ฐ ์ ์ฒ๋ฆฌ๊ธฐ ๋ฏน์ค์ธ์ด ์ฐ์ํฉ๋๋ค. -
๋ฒค๋ ํ๋ฆฌํฝ์ฑ: Autoprefixer๊ฐ ์ด ํ์ฒ๋ฆฌ ์์ ์ ์ฒ๋ฆฌํ์ง๋ง, ์ ์ฒ๋ฆฌ๊ธฐ ๋ฏน์ค์ธ์ ๋ฒค๋ ํ๋ฆฌํฝ์ค๋ฅผ ์ง์ ์บก์ํํ ์ ์์ผ๋ฉฐ, ์ด๋ ์ฃผ์ํ ์ญ์ฌ์ ์ฌ์ฉ ์ฌ๋ก์์ต๋๋ค.
-
๊น์ ์ค์ฒฉ ๋ฐ ์์(์ฃผ์ ์๋ง): ์ ์ฒ๋ฆฌ๊ธฐ๋ ์ ํ์๋ฅผ ์ค์ฒฉํ๊ณ ์์ฑ์ ์์ํ๊ธฐ ์ฝ๊ฒ ๋ง๋ค์ด ๋ณต์กํ ์ปดํฌ๋ํธ ์คํ์ผ๋ง์ ๋จ์ํํ ์ ์์ต๋๋ค(๊ทธ๋ฌ๋ ์ค์ฒฉ์ ๊ณผ๋ํ๊ฒ ์ฌ์ฉํ๋ฉด ์ง๋์น๊ฒ ๊ตฌ์ฒด์ ์ด๊ณ ์ฌ์ ์ํ๊ธฐ ์ด๋ ค์ด CSS๊ฐ ๋ ์ ์์ต๋๋ค).
-
ํ๋ฆฝ๋ ํด์ฒด์ธ: ํ์ด ์ด๋ฏธ ์ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ฌ์ฉํ๊ณ ์๊ณ ๊ทธ ์ฃผ๋ณ์ ์ฑ์ํ ์ํฌํ๋ก์ฐ๊ฐ ์๋ค๋ฉด, ๋ฏน์ค์ธ ๊ธฐ๋ฅ์ ํ์ฉํ๋ ๊ฒ์ด ์์ฐ์ค๋ฝ์ต๋๋ค.
-
๋งค๊ฐ๋ณ์ํ๋ ์ฌ์ฌ์ฉ์ฑ: ์ฌ๋ฌ ์ธ์๋ฅผ ๋ฐ๋ ๊ณ ๋๋ก ์ฌ์ฉ์ ์ ์ ๊ฐ๋ฅํ ์คํ์ผ ๋ธ๋ก(์: ๋์ ๊ทธ๋ฆฌ๋ ์ปฌ๋ผ ๋๋ ์ ์ฐํ ๋ฒํผ ํฌ๊ธฐ๋ฅผ ์ํ ๋ฏน์ค์ธ)์ ๋ง๋ค์ด์ผ ํ ๋ ํ์ํฉ๋๋ค.
๋ค์ดํฐ๋ธ CSS(๋ฐ ์ฌ์ฉ์ ์ง์ ์์ฑ)์๋ง ์์กดํด์ผ ํ ๋
-
๋ ๊ฐ๋จํ ํ๋ก์ ํธ: ์๊ท๋ชจ ํ๋ก์ ํธ๋ ๋ ๋ณต์กํ ์คํ์ผ๋ง ์๊ตฌ๊ฐ ์๋ ํ๋ก์ ํธ์ ๊ฒฝ์ฐ, ์ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ํ ๋น๋ ๋จ๊ณ์ ์ค๋ฒํค๋๊ฐ ์ ๋นํ๋์ง ์์ ์ ์์ต๋๋ค.
-
์ฑ๋ฅ์ด ์ค์ํ ํ๊ฒฝ: ๋น๋ ํด์ฒด์ธ์ ๋ณต์ก์ฑ์ ์ค์ด๋ฉด ๋งค์ฐ ๊ฐ๊ฒฐํ ํ๊ฒฝ์์ ๊ฐ๋ฐ ์ฃผ๊ธฐ๊ฐ ๋นจ๋ผ์ง ์ ์์ต๋๋ค.
-
๊ฐ ์ฌ์ฌ์ฉ์ฑ: ๋จ์ํ ๊ณตํต ๊ฐ(์์, ๊ธ๊ผด, ๊ฐ๊ฒฉ ๋จ์)์ ์ฌ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, CSS ์ฌ์ฉ์ ์ง์ ์์ฑ์ด ๋ค์ดํฐ๋ธํ๊ณ , ์ฑ๋ฅ์ด ๋ฐ์ด๋๋ฉฐ, ๊ฐ๋ฐ์ ์นํ์ ์ธ ํด๊ฒฐ์ฑ ์ ๋๋ค.
-
๋ฐํ์ ์กฐ์: ์ฌ์ฉ์ ์ง์ ์์ฑ์ ๋ฐํ์์ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์กฐ์ํ ์ ์์ผ๋ฉฐ, ์ด๋ ์ ์ CSS๋ก ์ปดํ์ผ๋๋ ์ ์ฒ๋ฆฌ๊ธฐ ๋ฏน์ค์ธ์ผ๋ก๋ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
-
์ํธ ์ด์ฉ์ฑ: ์ฌ์ฉ์ ์ง์ ์์ฑ์ ๋ธ๋ผ์ฐ์ ์ ๋ค์ดํฐ๋ธํ๋ฏ๋ก ์์ค ๋งต์ด๋ ์ ์ฒ๋ฆฌ๊ธฐ์ ๋ํ ์ง์ ์์ด๋ ๋ณดํธ์ ์ผ๋ก ์ดํด๋๊ณ ๋๋ฒ๊น ํ ์ ์์ต๋๋ค.
ํ์ด๋ธ๋ฆฌ๋ ์ ๊ทผ ๋ฐฉ์๊ณผ ํ์ฒ๋ฆฌ๊ธฐ
๋ง์ ํ๋ ๊ฐ๋ฐ ์ํฌํ๋ก์ฐ๋ ํ์ด๋ธ๋ฆฌ๋ ์ ๊ทผ ๋ฐฉ์์ ์ฑํํฉ๋๋ค. Sass์ ๊ฐ์ ์ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ(๋ณต์กํ ๋ก์ง ๋ฐ ๋งค๊ฐ๋ณ์ํ๋ ์คํ์ผ์ ์ํ ๋ฏน์ค์ธ ํฌํจ)์ ์ํด ์ฌ์ฉํ๊ณ , ๊ทธ ๋ค์์ PostCSS์ ๊ฐ์ ํ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ ๋๋ค. PostCSS์ ํ๋ฌ๊ทธ์ธ์ ๋ค์๊ณผ ๊ฐ์ ์์ ์ ์ํํ ์ ์์ต๋๋ค:
-
์๋ ํ๋ฆฌํฝ์ฑ: ๋ฒค๋ ํ๋ฆฌํฝ์ค๋ฅผ ์๋์ผ๋ก ์ถ๊ฐํฉ๋๋ค.
-
CSS ์ถ์: ํ์ผ ํฌ๊ธฐ๋ฅผ ์ค์ ๋๋ค.
-
๋ฏธ๋ CSS ํด๋ฆฌํ๋ง: ์๋กญ๊ณ ์คํ์ ์ธ CSS ๊ธฐ๋ฅ์ ๋๋ฆฌ ์ง์๋๋ CSS๋ก ๋ณํํฉ๋๋ค(๋ ์ด์
@apply
๋ ์๋). -
์ฌ์ฉ์ ์ง์ ์์ฑ ํด๋ฐฑ: ๊ตฌํ ๋ธ๋ผ์ฐ์ ์์ ํธํ์ฑ์ ๋ณด์ฅํฉ๋๋ค.
์ด ์กฐํฉ์ ๊ฐ๋ฐ์๊ฐ ๋ ์ธ๊ณ์ ์ฅ์ ์ ๋ชจ๋ ํ์ฉํ ์ ์๊ฒ ํฉ๋๋ค: ์์ฑ์ ์ํ ์ ์ฒ๋ฆฌ๊ธฐ์ ํํ๋ ฅ๊ณผ ๋ฐฐํฌ๋ฅผ ์ํ ํ์ฒ๋ฆฌ๊ธฐ์ ์ต์ ํ ๋ฐ ๋ฏธ๋ ๋๋น ๊ธฐ๋ฅ์ ๋๋ค.
๋ฏน์ค์ธ ์ ์ฉ์ ์ํ ๊ธ๋ก๋ฒ ๋ชจ๋ฒ ์ฌ๋ก
์ ํํ ๋๊ตฌ์ ๊ด๊ณ์์ด, ๋ฏน์ค์ธ ์ ์ฉ์ ๋ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ฑํํ๋ ๊ฒ์ ๊นจ๋ํ๊ณ , ํ์ฅ ๊ฐ๋ฅํ๋ฉฐ, ํ์ ๊ฐ๋ฅํ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ์ ์งํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. ํนํ ์ผ๊ด์ฑ๊ณผ ๋ช ํ์ฑ์ด ๊ฐ์ฅ ์ค์ํ ๊ธ๋ก๋ฒ ํ์๊ฒ๋ ๋์ฑ ๊ทธ๋ ์ต๋๋ค.
1. ๋ฏน์ค์ธ ๋ค์ด๋ฐ ์ปจ๋ฒค์
๋ฏน์ค์ธ์ ๋ํด ๋ช ํํ๊ณ , ์ค๋ช ์ ์ด๋ฉฐ, ์ผ๊ด๋ ๋ค์ด๋ฐ ์ปจ๋ฒค์ ์ ์ฑํํ์ญ์์ค. ์ผ๋ฐฅ ์ผ์ด์ค(kebab-case)๋ฅผ ์ฌ์ฉํ๊ณ ์ด๋ฆ์ด ๋ฏน์ค์ธ์ ๋ชฉ์ ์ ์ ํํ๊ฒ ๋ฐ์ํ๋๋ก ํ์ญ์์ค.
-
์ข์ ์:
@mixin flex-center
,@mixin button-variant($color)
,@mixin font-size($scale)
-
๋์ ์:
@mixin fc
,@mixin btn(c)
,@mixin fs
(๋๋ฌด ์ํธ ๊ฐ์)
2. ๋ฏน์ค์ธ ๊ตฌ์ฑ (ํ์ ๋ฐ ๋ชจ๋)
ํ๋ก์ ํธ๊ฐ ์ฑ์ฅํจ์ ๋ฐ๋ผ ๋ฏน์ค์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ปค์ง ๊ฒ์
๋๋ค. ๋ฏน์ค์ธ์ ๋
ผ๋ฆฌ์ ์ธ ํ์
ํ์ผ(์: _mixins.scss
, _typography.scss
, _buttons.scss
)๋ก ๊ตฌ์ฑํ๊ณ ์ฃผ ์คํ์ผ์ํธ๋ก ๊ฐ์ ธ์ต๋๋ค. ์ด๋ ๋ชจ๋์ฑ์ ์ด์งํ๊ณ ๊ฐ๋ฐ์๊ฐ ๊ธฐ์กด ๋ฏน์ค์ธ์ ์ฝ๊ฒ ์ฐพ๊ณ ์ฌ์ฌ์ฉํ ์ ์๊ฒ ํฉ๋๋ค.
์์ ๊ตฌ์กฐ:
scss/
โโโ base/
โ โโโ _reset.scss
โ โโโ _typography.scss
โโโ components/
โ โโโ _button.scss
โ โโโ _card.scss
โโโ layouts/
โ โโโ _grid.scss
โโโ utilities/
โ โโโ _mixins.scss /* ๋ชจ๋ ๋ฒ์ฉ ๋ฏน์ค์ธ */
โ โโโ _functions.scss
โโโ vendors/
โ โโโ _normalize.scss
โโโ main.scss
_mixins.scss
ํ์ผ์ด ๋๋ฌด ์ปค์ง๋ฉด ๋ค๋ฅธ ์นดํ
๊ณ ๋ฆฌ์ ๋ฏน์ค์ธ์ ์ํ ํน์ ํ์ผ(์: _mixins-layout.scss
, _mixins-effects.scss
)์ ๊ฐ์ง ์ ์์ต๋๋ค.
3. ๋ฏน์ค์ธ ๋ฌธ์ํ
๋๊ท๋ชจ ๋๋ ๊ธ๋ก๋ฒ ๋ถ์ฐ ํ์ ๊ฒฝ์ฐ, ๋ฏน์ค์ธ์ ๋ํ ์ฒ ์ ํ ๋ฌธ์ํ๋ ํ์์ ์ ๋๋ค. ๊ฐ ๋ฏน์ค์ธ์ด ๋ฌด์์ ํ๋์ง, ์ด๋ค ์ธ์๋ฅผ ๋ฐ๋์ง(ํ์ , ๊ธฐ๋ณธ๊ฐ), ๊ทธ๋ฆฌ๊ณ ์ฌ์ฉ ์์ ๋ฅผ ์ ๊ณตํ์ฌ ์ค๋ช ํ์ญ์์ค. SassDoc๊ณผ ๊ฐ์ ๋๊ตฌ๋ Sass ํ์ผ์ ์ฃผ์์์ ์๋์ผ๋ก ๋ฌธ์๋ฅผ ์์ฑํ ์ ์์ผ๋ฉฐ, ์ด๋ ๋ค์ํ ๋ฐฐ๊ฒฝ์ ๊ฐ์ง ์๋ก์ด ํ์์ ์จ๋ณด๋ฉ์ ํฐ ๋์์ด ๋ฉ๋๋ค.
์์: ๋ฏน์ค์ธ ๋ฌธ์ํํ๊ธฐ
/// ๋ฐ์ํ ํจ๋ฉ ์ ํธ๋ฆฌํฐ๋ฅผ ์์ฑํฉ๋๋ค.
/// @param {Number} $max - ์ ํธ๋ฆฌํฐ ํด๋์ค์ ์ต๋ ์ธ๋ฑ์ค (์: .padding-5์ ๊ฒฝ์ฐ 5).
/// @param {String} $step - ํจ๋ฉ์ ๊ธฐ๋ณธ ๋จ์ (์: '5px', '0.5rem').
/// @example
/// @include generate-padding-utilities(3, 10px);
/// // .padding-1 { padding: 10px; }
/// // .padding-2 { padding: 20px; }
/// // .padding-3 { padding: 30px; }
@mixin generate-padding-utilities($max, $step) {
/* ... ๋ฏน์ค์ธ ์ฝ๋ ... */
}
4. ์ฑ๋ฅ ๊ณ ๋ ค ์ฌํญ
๋ฏน์ค์ธ์ด ๋ ๊นจ๋ํ ์ฝ๋๋ฅผ ์ด์งํ์ง๋ง, ์ปดํ์ผ๋ CSS ์ถ๋ ฅ์ ์ ์ํด์ผ ํฉ๋๋ค:
-
์ถ๋ ฅ ํฌ๊ธฐ: ๋ฏน์ค์ธ์ด
@include
๋ ๋๋ง๋ค ํด๋น CSS ์์ฑ์ด ์ปดํ์ผ๋ ์ถ๋ ฅ์ ๋ณต์ ๋ฉ๋๋ค. ์ฌ๋ฌ ๋ฒ ํฌํจ๋๋ ํฐ ๋ฏน์ค์ธ์ ๊ฒฝ์ฐ, ์ด๋ ๋ ํฐ CSS ํ์ผ ํฌ๊ธฐ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ๋น๋ ๊ณผ์ ์์ ์ถ์(minification)๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฅผ ์ํํ์ญ์์ค. -
์ปดํ์ผ ์๊ฐ: ๊ด๋ฒ์ํ ๋ฃจํ๋ ์กฐ๊ฑด๋ถ ๋ก์ง์ด ์๋ ๋งค์ฐ ๋ณต์กํ ๋ฏน์ค์ธ ๋๋ ์๋ง์ ๋ฏน์ค์ธ ํฌํจ์ CSS ์ปดํ์ผ ์๊ฐ์ ์ฆ๊ฐ์ํฌ ์ ์์ต๋๋ค. ๊ฐ๋ฅํ ๊ฒฝ์ฐ ๋ฏน์ค์ธ์ ํจ์จ์ ์ผ๋ก ์ต์ ํํ์ญ์์ค.
-
๋ช ์๋(Specificity): ๋ฏน์ค์ธ ์์ฒด๋ ํฌํจ๋ ์ ํ์๋ฅผ ๋์ด์๋ ๋ช ์๋ ๋ฌธ์ ๋ฅผ ์ผ์ผํค์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ฏน์ค์ธ์ ์ํด ์์ฑ๋ CSS๊ฐ ์ ๋ฐ์ ์ธ CSS ์ํคํ ์ฒ์ ๋ช ์๋ ๊ท์น๊ณผ ์ ํตํฉ๋๋๋ก ํ์ญ์์ค.
5. ์ ๊ทผ์ฑ ์ํฅ
๋ฏน์ค์ธ์ CSS ์์ฑ ๋๊ตฌ์ด์ง๋ง, ์์ฑํ๋ ์คํ์ผ์ ์ ๊ทผ์ฑ์ ์ง์ ์ ์ธ ์ํฅ์ ๋ฏธ์นฉ๋๋ค. ํฌ์ปค์ค ์ํ, ์์ ๋๋น ๋๋ ์ํธ์์ฉ ์์์ ๊ด๋ จ๋ ๋ชจ๋ ๋ฏน์ค์ธ์ด WCAG(์น ์ฝํ ์ธ ์ ๊ทผ์ฑ ๊ฐ์ด๋๋ผ์ธ) ํ์ค์ ์ค์ํ๋๋ก ํ์ญ์์ค. ์๋ฅผ ๋ค์ด, ๋ฒํผ ๋ฏน์ค์ธ์ ์ ์ ํ ํฌ์ปค์ค ์คํ์ผ์ ํฌํจํด์ผ ํฉ๋๋ค.
์์: ๋ฏน์ค์ธ์ ์ ๊ทผ์ฑ ์๋ ํฌ์ปค์ค ์คํ์ผ ์ ์ฉ
@mixin interactive-focus-styles {
&:focus-visible {
outline: 2px solid var(--focus-ring-color, #007bff);
outline-offset: 2px;
}
}
.my-link {
@include interactive-focus-styles;
color: blue;
text-decoration: underline;
}
:focus-visible
(๋๋ ๊ทธ ํด๋ฆฌํ)์ ์ฌ์ฉํ๋ ๊ฒ์ ์ฌ์ฉ์๊ฐ ํค๋ณด๋๋ ๋ค๋ฅธ ํฌ์ธํฐ๊ฐ ์๋ ์
๋ ฅ์ผ๋ก ํ์ํ ๋๋ง ํฌ์ปค์ค ์ค๊ณฝ์ ์ ํ์ํ๋ฏ๋ก ์ ๊ทผ์ฑ์ ์ํ ํ๋์ ์ธ ๋ชจ๋ฒ ์ฌ๋ก์
๋๋ค.
6. ์ ์ง๋ณด์์ฑ ๋ฐ ํ ํ์
๊ธ๋ก๋ฒ ํ์๊ฒ๋ ์ผ๊ด์ฑ์ด ํต์ฌ์ ๋๋ค. ์ธ์ ์๋ก์ด ๋ฏน์ค์ธ์ ๋ง๋ค์ง, ์ธ์ ๊ธฐ์กด ๋ฏน์ค์ธ์ ์์ ํ ์ง, ์ธ์ ๋ ๊ฐ๋จํ ์ ํธ๋ฆฌํฐ ํด๋์ค๋ ๋ค์ดํฐ๋ธ CSS ์ฌ์ฉ์ ์ง์ ์์ฑ์ ์ ํํ ์ง์ ๋ํ ๋ช ํํ ๊ฐ์ด๋๋ผ์ธ์ ์ค์ ํ์ญ์์ค. ์ฝ๋ ๋ฆฌ๋ทฐ๋ ์ด๋ฌํ ๊ฐ์ด๋๋ผ์ธ ์ค์๋ฅผ ๋ณด์ฅํ๊ณ ๋ค์ํ ๊ธฐ์ ๋ฐฐ๊ฒฝ์ ๊ฐ์ง ๊ฐ๋ฐ์๋ค์ด ์ดํดํ๊ณ ๊ธฐ์ฌํ ์ ์๋ ๊ณ ํ์ง์ ๊ฐ๋ ์ฑ ์๋ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ์ ์งํ๋ ๋ฐ ํ์์ ์ ๋๋ค.
CSS ์ฌ์ฌ์ฉ์ฑ์ ๋ฏธ๋ ๋ํฅ
์น ํ๋ซํผ์ ๋์์์ด ์งํํ๊ณ ์์ต๋๋ค. ์ ์ฒ๋ฆฌ๊ธฐ ๋ฏน์ค์ธ์ ์ฌ์ ํ ๋งค์ฐ ์ค์ํ์ง๋ง, CSS ์ํน ๊ทธ๋ฃน์ ๋ฏธ๋์ ์ฐ๋ฆฌ๊ฐ ์ฌ์ฌ์ฉ์ฑ์ ์ ๊ทผํ๋ ๋ฐฉ์์ ์ํฅ์ ์ค ์ ์๋ ์๋ก์ด ๋ค์ดํฐ๋ธ ๊ธฐ๋ฅ์ ๊ณ์ ํ์ํ๊ณ ์์ต๋๋ค.
-
์ปจํ ์ด๋ ์ฟผ๋ฆฌ: ์ง์ ์ ์ธ ๋ฏน์ค์ธ ๋์ฒด์ฌ๋ ์๋์ง๋ง, ์ปจํ ์ด๋ ์ฟผ๋ฆฌ(
@container
)๋ ์์๊ฐ ๋ทฐํฌํธ๊ฐ ์๋ ๋ถ๋ชจ ์ปจํ ์ด๋์ ํฌ๊ธฐ์ ๋ฐ๋ผ ์คํ์ผ์ ์ง์ ํ ์ ์๊ฒ ํฉ๋๋ค. ์ด๋ ๋ ์ง์ ์ผ๋ก ์บก์ํ๋๊ณ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ฉฐ, ์ปดํฌ๋ํธ์ ๋ด๋ถ ๋ ์ด์์์ด ํ์ด์ง์ ์ด๋ ์์น์ ์๋ ์๊ด์์ด ์ฌ์ฉ ๊ฐ๋ฅํ ๊ณต๊ฐ์ ๋ฐ๋ผ ์ ์ํ ์ ์๊ฒ ํฉ๋๋ค. ์ด๋ ๋ณต์กํ ๊ธ๋ก๋ฒ ๋ฏธ๋์ด ์ฟผ๋ฆฌ ๋ฏน์ค์ธ์ ํ์์ฑ์ ์ค์ฌ์ค๋๋ค. -
CSS ๋ ์ด์ด(
@layer
): CSS ๋ ์ด์ด๋ ์คํ์ผ์ํธ๋ฅผ ๋ณ๊ฐ์ ๋ ์ด์ด๋ก ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ฌ ๊ฐ๋ฐ์์๊ฒ ์บ์ค์ผ์ด๋์ ๋ํ ๋ ๋ง์ ์ ์ด๊ถ์ ์ค๋๋ค. ์ด๋ ๋ช ์๋๋ฅผ ๊ด๋ฆฌํ๊ณ ์๋ํ์ง ์์ ์คํ์ผ ์ฌ์ ์๋ฅผ ๋ฐฉ์งํ๋ ๋ฐ ๋์์ด ๋๋ฉฐ, ๊ฐ์ ์ ์ผ๋ก ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์คํ์ผ์ ๋ ๋์ ๊ตฌ์ฑ์ ์ง์ํฉ๋๋ค. -
๋ฏธ๋์ ๋ค์ดํฐ๋ธ '๋ฏน์ค์ธ'๊ณผ ์ ์ฌํ ๊ธฐ๋ฅ:
@apply
๋ ์ ์ฒ๋ฆฌ๊ธฐ ๋ฏน์ค์ธ๊ณผ ์ ์ฌํ ๋ค์ดํฐ๋ธ CSS ๊ธฐ๋ฅ์ ๋ํ ๋ ผ์๋ ๊ณ์๋๊ณ ์์ต๋๋ค. ์ปค๋ฎค๋ํฐ๋ ์ ์ธ์ ๊ทธ๋ฃนํํ ํ์์ฑ์ ์ธ์ ํ๊ณ ์์ผ๋ฉฐ, ๋ฏธ๋์ ์ฌ์์ ์ฑ๋ฅ์ด ๋ฐ์ด๋๊ณ ์๋ฏธ๋ก ์ ์ผ๋ก ๊ฑด์ ํ ๋ฐฉ์์ผ๋ก ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์๋ก์ด ๋ฉ์ปค๋์ฆ์ ๋์ ํ ์ ์์ต๋๋ค.
์ด๋ฌํ ๋ฐ์ ์ ๋ํด ์ ๋ณด๋ฅผ ์ป๋ ๊ฒ์ CSS ์ํคํ ์ฒ๋ฅผ ๋ฏธ๋์ ๋๋นํ๊ณ ๋ฏน์ค์ธ ์ ์ฉ ์ ๋ต์ด ์ต์ ์น ํ์ค๊ณผ ์ผ์นํ๋๋ก ๋ณด์ฅํ๋ ๋ฐ ํ์์ ์ ๋๋ค.
๊ฒฐ๋ก
ํนํ ๋ฏน์ค์ธ ์ ์ฉ์ ๋งฅ๋ฝ์์ 'CSS apply ๊ท์น'์ ํ๋ ํ๋ก ํธ์๋ ๊ฐ๋ฐ์์ ์ค์ถ์ ์ธ ๊ฐ๋
์ ๋ํ๋
๋๋ค. ๋ค์ดํฐ๋ธ CSS @apply
๊ท์น์ ์ฌ์ฉ ์ค๋จ๋์์ง๋ง, CSS์์ ์ฌ์ฌ์ฉ์ฑ, ๋ชจ๋์ฑ ๋ฐ ์ ์ง๋ณด์์ฑ์ ๋ํ ๊ทผ๋ณธ์ ์ธ ํ์์ฑ์ ๊ทธ ์ด๋ ๋๋ณด๋ค ๊ฐํ๊ฒ ๋จ์ ์์ต๋๋ค.
Sass, Less, Stylus์ ๊ฐ์ CSS ์ ์ฒ๋ฆฌ๊ธฐ๋ ๊ณ์ํด์ ๊ฐ๋ ฅํ๊ณ ์ ์ฐํ ๋ฏน์ค์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ๊ฐ๋ฐ์๊ฐ ๋ ํจ์จ์ ์ด๊ณ , ๋์ ์ด๋ฉฐ, ๊ด๋ฆฌํ๊ธฐ ์ฌ์ด ์คํ์ผ์ํธ๋ฅผ ์์ฑํ ์ ์๋๋ก ์ง์ํฉ๋๋ค. ์ธ์, ์ฝํ ์ธ ๋ธ๋ก, ์กฐ๊ฑด๋ถ ๋ก์ง์ด ์๋ ๋ฏน์ค์ธ์ ํ์ฉํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ ๋ณต์กํ ์คํ์ผ๋ง ํจํด์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ๋ก ์ถ์ํํ์ฌ ๋๊ท๋ชจ ํ๋ก์ ํธ ๋ฐ ๊ธ๋ก๋ฒ ๋์์ธ ์์คํ ์ ๋ฐ์ ๊ฑธ์ณ ๋ฐ๋ณต์ ๊ทน์ ์ผ๋ก ์ค์ด๊ณ ์ผ๊ด์ฑ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
๋ํ, ๊ฐ ์ฌ์ฌ์ฉ์ฑ์ ์ํ ๋ค์ดํฐ๋ธ CSS ์ฌ์ฉ์ ์ง์ ์์ฑ์ ํ์ ์ดํดํ๊ณ , ์ ํธ๋ฆฌํฐ ํด๋์ค ๋ฐ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ CSS์ ์ ๋ต์ ์ฌ์ฉ๊ณผ ๊ฒฐํฉํ๋ฉด ๊ณ ์ฑ๋ฅ์ ์ ์ง๋ณด์ ๊ฐ๋ฅํ ์น ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ ํดํท์ด ์์ฑ๋ฉ๋๋ค. ์ ์ฒ๋ฆฌ๊ธฐ์ ๊ฐ์ ๊ณผ ๋ค์ดํฐ๋ธ CSS ํจ์จ์ฑ์ ์กฐํ, ๊ทธ๋ฆฌ๊ณ ๋ค์ด๋ฐ, ๊ตฌ์ฑ, ๋ฌธ์ํ, ์ ๊ทผ์ฑ์ ๋ํ ๊ธ๋ก๋ฒ ๋ชจ๋ฒ ์ฌ๋ก์ ์ ์คํ ์ค์๋ ์ค๋๋ ์ ๋ฌธ์ ์ธ CSS ๊ฐ๋ฐ์ ํน์ง์ ๋๋ค.
์น ํ๋ซํผ์ด ์งํํจ์ ๋ฐ๋ผ ์คํ์ผ๋ง์ ๋ํ ์ฐ๋ฆฌ์ ์ ๊ทผ ๋ฐฉ์๋ ๋ณํ ๊ฒ์ ๋๋ค. ๋ฏน์ค์ธ ์ ์ฉ ๊ธฐ์ ์ ๋ง์คํฐํ๊ณ ์๋ก์ด CSS ๊ธฐ๋ฅ์ ์ฃผ์๋ฅผ ๊ธฐ์ธ์์ผ๋ก์จ ๊ฐ๋ฐ์๋ ์์ ์ ์คํ์ผ์ํธ๊ฐ ๊ธฐ๋ฅ์ ์ผ ๋ฟ๋ง ์๋๋ผ ์ฐ์ํ๊ณ , ํ์ฅ ๊ฐ๋ฅํ๋ฉฐ, ์ง์ ํ ๊ธ๋ก๋ฒ ๊ณ ๊ฐ์ ์ํ ๊ตฌ์ถ ๊ณผ์ ์ ๋๋นํ ์ ์๋๋ก ๋ณด์ฅํ ์ ์์ต๋๋ค.