CSS는 쉽고 재미있는 언어이지만, 작업이 고도화될수록 불필요한 선택자의 과용과 연산 기능의 한계, 구문의 부재 등으로 코드가 복잡해지고 아쉬움이 발생한다. 이를 보완하기 위해 나온 게 CSS Preprocessor이다.
CSS Preprocessor은 CSS 전(예비)처리기이다. CSS가 동작하기 전에 사용하는 기능으로, CSS를 편리하게 이용할 수 있도록 도와주며 추가 기능이 있는 확장판 언어이다.
.a {
width: 100px;
}
li {
list-style:none;
}
li:hover {
color: red;
}
.a {
width: 100px;
li {
list-style:none;
}
&:hover {
color: red;
}
}
위와 같이 SCSS는 CSS 문법과 굉장히 유사하면서도 다음과 같은 추가 기능들을 제공한다.
SCSS : Sassy CSS (멋진 CSS)
SASS : Syntactically Awesome Style Sheets (문법적으로 짱 멋진 스타일시트)
Sass의 3버전에서 새롭게 등장한 SCSS는 CSS 구문과 완전히 호환되도록 새로운 구문을 도입해 만든 언어이다. 즉 Sass의 모든 기능을 지원하는 CSS의 상위집합(Superset) 이다.
간단하게 {}
(중괄호)와 ;
(세미콜론)의 유무로 구분할 수 있다.
.list {
width: 100px;
li {
color: red;
&:last-child {
margin-right: -10px;
}
}
}
인라인 코드를 작성 가능하고, CSS와 유사하다.
.list
width: 100px
li
color: red
&:last-child
margin-right: -10px
더 간결하고 작성하기 편리하며, 코드가 깔끔해진다.
각자의 장단점이 있기 때문에 상황에 맞춰서 선택 가능하지만, 보통은 SCSS를 추천한다.
공식 문법: 공식 레퍼런스는 SCSS 문법을 기준으로 모든 문법을 설명하고 예시를 보여준다.
더 넓은 사용자: 다수의 라이브러리, 프레임워크가 SCSS 문법을 활용하는 등 새로운 문법이 더욱 널리 쓰인다.
CSS 호환성: 친근한 CSS 문법은 Sass와 CSS 사이의 심리적 틈을 줄여주고, 기능적으로도 확장성을 높인다.
여러 줄 쓰기 지원: Sass 문법은 들여쓰기와 줄 바꿈이 문법의 중요한 요소이기 때문에, 반대로 여러 줄 쓰기를 지원하지 않는다.
SCSS와 SASS는 웹에서 직접 동작하지 않는다. 어디까지나 최종에는 표준 CSS만이 사용되기 때문에, 전처리기에서 작성한 후 CSS로 컴파일(Compile) 해야 한다.
컴파일 방법으로는 여러가지가 있으나, 입문하는 과정에서는 아래의 두 가지 방법을 추천한다.
간단한 코드를 테스트해보고 싶을 경우 SassMeister 웹사이트를 이용할 수 있다.
페이지 접속 후 Sass/SCSS로 코딩할 경우 실시간으로 CSS 변환이 가능하다.
아래의 확장 프로그램을 설치한 후 VSCode를 재접속하면 오른쪽 아래에 Watch Sass 버튼이 생길 것이다. SCSS 문법으로 언어를 작성한 후 해당 버튼을 누르면 자동으로 연동되는 CSS 파일이 생성된다.
@import
하여 다른 파일을 불러온다면, 모든 파일을 다 CSS로 변환할 필요가 없으므로 파일 앞에 언더바 _
를 붙여주면 컴파일을 막을 수 있다.부모 요소 안에 자식 요소를 작성할 수 있다.
하지만 과하게 작성하면 읽기 힘드므로 최대 3뎁스까지 추천한다.
.section {
width: 100%;
.list {
padding: 20px;
}
}
.a {
background : {
image: url("./assets/a.svg");
position: center;
repeat: no-repeat;
size: 15px;
}
}
&
(엠퍼샌트)&
(엠퍼샌트) 를 사용한다..btn {
position: absolute;
&:active { /* .btn.active {} */
color: red;
}
&::after {
content: "";
}
}
@at-root
@at-root
키워드를 사용하면 중첩에서 벗어날 수 있다.
.a {
display: flex;
justify-content: center;
.a-content {
font-size: 14px;
@at-root i {
opacity: 0.5;
}
}
}
$
기호로 변수 만든다.
//$변수 : 값
$bgColor : #FFF;
선언된 블록({}) 내에서만 유효범위를 가진다.
변수 $color는 .box1의 블록 안에서 설정되었기 때문에, 블록 밖의 .box2에서는 적용되지 않는다.
위에서 @at-root
를 사용하는 이유이다.
.box1 {
$color: #111;
background: $color;
}
// Error
.box2 {
background: $color;
}
!global
플래그를 사용하면 유효 범위를 전역(Global)로 변경할 수 있다..box1 {
$color: #111 !global;
background: $color;
}
.box2 {
background: $color;
} // 가능
color: darken ($color: ,$amount: n%); // 어둡게
color: lighten ($color: ,$amount: n%);// 밝게
color: saturate ($color: ,$amount: n%); // 채도 올림
color: desaturate ($color: ,$amount: n%); // 채도 낮춤
color: adjust-hue ($color: ,$degrees: deg); // 색조 변화
color: rgba(color, 0.5); //투명도 변화
특정 선택자가 다른 선택자의 모든 스타일을 가져야하는 경우 (코드의 중복) 일 경우 사용할 수 있다.
.btn {
padding: 10px;
margin: 10px;
background: blue;
}
.btn-danger {
@extend .btn;
background: red;
}
.btn, .btn-danger {
padding: 10px;
margin: 10px;
background: blue;
}
.btn-danger {
background: red;
}
%
placeholder%
로 임시 클래스를 만들 수 있다. html
파일에는 btn-1
, btn-2
클래스만 존재하지만, scss 내부에 %btn
이라는 컴파일 되지 않는 임시 클래스를 만들어 작성 후 @extend
를 사용해 두 클래스의 속성을 이어서 작성할 수 있다.
%btn {
padding: 10px;
margin: 10px;
}
.btn-red {
@extend %btn;
background-color: red;
}
.btn-blue {
@extend %btn;
background-color: blue;
}
🤔 Mixin 과 Extend 차이점
mixin
는 (관계 없는) 선택자에서 조금 다른 스타일을 적용할 때 사용extend
는 관계 있는 선택자들의 동일한 소스코드 적용시 사용
@mixin name
을 통해 생성을 하고, extend
와 같이 @include name
을 통해 불러올 수 있다.
@mixin name{ } // 생성
.btn {
@include name; // 사용
}
mixin
은 함수처럼 매개변수(parameter)와 인수(Arguments)를 가질 수 있다.$
달러 사인을 넣어야 한다.@mixin dash-line($parameter){
}
.btn {
@include dash-line($arguments);
}
@mixin dash-line($width: 50px){ }
null
을 사용하거나, 매개변수 명과 인수 값을 직접 언급해야 한다.@mixin btn ($width:100px, $height:50px, $radius:10px) {
width: $width;
height: $height;
border-radius: $radius;
}
// 값 비우기
.btn1 {
@include btn (500px, null, 20px)
}
// 중앙값 주지 않기
.btn2 {
@include btn (200px, $radius:20px)
}
CSS에서는 calc()
을 사용하여 연산한다.
하지만 SCSS의 경우 괄호 없이도 연산이 가능하다.
.box {
width: 20px + 20px; // 더하기
height: 40px - 10px; // 빼기
font-size: 10px * 2; // 곱하기
margin: ( 30px / 2 ); // 나누기
}
단, 나누기의 경우 이미 다른 기능으로 사용되고 있어 사용되지 않을 수 있다. 이럴 경우 아래의 조건 중 하나를 만족해야 한다.
()
로 묶여있는 경우@use "sass:math";
.box {
width: math.div(100px, 2);
} // division (분자, 분모)
추가적인 참고: sass:math
산술 연산자
종류 | 설명 | 주의사항 |
---|---|---|
+ | 더하기 | |
- | 빼기 | |
* | 곱하기 | 하나 이상의 값이 반드시 숫자(Number) |
/ | 나누기 | 오른쪽 값이 반드시 숫자(Number) |
% | 나머지 |
비교 연산자
종류 | 설명 |
---|---|
== | 동등 |
!= | 부등 |
< | 대소 / 보다 작은 |
> | 대소 / 보다 큰 |
<= | 대소 및 동등 / 보다 작거나 같은 |
>= | 대소 및 동등 / 보다 크거나 같은 |
논리 연산자
종류 | 설명 |
---|---|
and | 그리고 |
or | 또는 |
not | 부정 |
다른 파일을 불러와서 연결할 때 사용한다.
파일 확장자 명은 생략 가능하다.
@use "test" //test.scss 파일을 임포트
@use "test"
.box {
color: test.$bg-color;
// test 파일에 bg-color라는 변수를 선언한 상태
@use "test" as c;
.box {
color: c.$bg-color;
@import
는 @use
와 같이 모듈화된 다른 파일을 불러올 때 사용한다.
하지만 SCSS에서는 @import
규칙을 사용하는 것을 권장하지 않으며, 점진적으로 이를 완전히 제거할 것이라고 말한다.
sass에서는 if 함수가 사용 가능하다.
조건부 삼항 연산자처럼 활용되는데, if(조건, 표현식1, 표현식2)
구조를 가지고 두 개의 표현식 중 하나만 반환한다.
$width: 555px;
div {
width: if($width > 300px, $width, null);
}
$color: orange;
div {
@if $color == strawberry {
color: #FE2E2E;
} @else if $color == orange {
color: #FE9A2E;
} @else if $color == banana {
color: #FFFF00;
} @else {
color: #2A1B0A;
}
}
@for
는 스타일을 반복적으로 출력합니다.
@for
는 through
를 사용하는 형식과 to
를 사용하는 형식으로 나뉜다.
// 1부터 3번 반복
@for $i from 1 through 3 {
.through:nth-child(#{$i}) {
width : 20px * $i
}
}
// 1부터 3 직전까지만 반복(2번 반복)
@for $i from 1 to 3 {
.to:nth-child(#{$i}) {
width : 20px * $i
}
}
for in 문과 유사한 형식으로, 배열과 map 데이터를 반복할 때 사용한다.
// List Data
$fruits: (apple, orange, banana, mango);
.fruits {
@each $fruit in $fruits {
li.#{$fruit} {
background: url("/images/#{$fruit}.png");
}
}
}
//오브젝트
$ object : (
1 : orange,
2 : blue,
3 : yellow
);
@each $key, $color in $object {
.box-#{$key} {
background-color: $color;
}
}
REFERENCE
1 : Sass는 SCSS로 쓰세요
2 : CSS & SCSS & SASS
3 : Sass(SCSS) 완전 정복!