[아무튼 Sass] 2. 기본 작성법 익히기 - 중첩, 참조, 변수, 보간
프롤로그
[아무튼 Sass] 1. 시작하기의 다음 글입니다. 두 번째 글이지만 어느덧 반년만... 😉💦
이런 분들을 위한 글입니다.
- CSS를 다룰 수 있어요
- 하지만 Sass는 1도 몰라요
아무튼 Sass 시리즈
1. 시작하기 - Sass 개념, 컴파일러 설치
2. 기본 작성법 익히기 - 중첩, 참조, 변수, 보간 👈 Here!
3. 더 편하게 CSS 다루기 - mixin, extend, 모듈화(import/use)
4. 더 멋지게 활용하기 - 흐름제어, 내장 모듈, 함수
이번 글에서 다루는 것:
- 중첩, 부모참조 선택자
- 변수, 보간
- 인라인 주석
- 출력스타일 설정
1) 중첩: 이것이 "C"SS
지난 글에서는 Sass 만 설치하고 똑 끝나버려서 '왜 굳이 이걸 설치해서 써야하지 🤔' 하는 생각이 들 수도 있는데,
아무튼 Sass는 쓰기 편하니까 믿어주세요(?)
Sass가 제공하는 어썸한 문법들을 몇 가지 알아볼 건데, 그 중 하나는 CSS를 중첩해서 사용하는 점입니다.
CSS의 뜻은? 케스케이딩 스타일 시트죠!
넵. CSS의 가장 큰 특징은 "C", 바로 케스케이딩*에 있습니다.
*cascading: 위에서 아래로 흐르는
그래서 CSS는 .grand-parent > .parent > .child와 같이 부모에서 자식 순서로 작성합니다.
요소의 스타일은 상속을 통해 적용되고요.
엉뚱한 애한테 스타일이 상속되지 않도록 케스케이딩을 관리하는 게 CSS 작성의 중요 포인트죠.
하지만 CSS의 길고 길고 기다란 셀렉팅에선 cascading 의 느낌을 받을 수가 없는데요...
하지만 이걸 Sass 문법으로 작성한다면?!
계층 구조가 시각적으로 바뀌면서 한눈에 들어옵니다.
이제야 "Cascading" 이란 느낌이네요! 부모 선택자를 반복하지 않아도 되니 보기에도 훨씬 좋습니다.
설명은... 이게 끝이에요! 😋
어떻게 사용해야 할지 감이 오실 텐데, 중첩하고 싶은 만큼 대괄호{} 안에 자식 셀렉터를 넣으면 됩니다.
이렇게 중첩해서 쓰면 좋은 점은 어디서부터 어디까지가 셀렉터인지 한눈에 알 수 있다는 점입니다.
.wrap {
//...
.main {
//...
.section {
//...
.article {
//...
.title {
//...
}
}
}
}
}
하지만 얼마나 중첩해서 쓸 것인가는 고민이 필요한 부분입니다.
저는 너무 들여쓰는 경우 '그래서 얘 부모가 누구지...' 하고 한눈에 파악이 힘들 때가 있더라고요.
BEM 방법론을 사용한다면 Element 단위에서 끊어 쓰거나, CSS Module 을 사용한다면 어차피 중복되지 않을 테니 깊게 들여쓰지 않아도 되긴 하겠죠!
2) 부모참조: 이름을 물려받는 중입니다
Sass에는 특별한 선택자가 몇 개 있는데, 그 중 하나인 &
를 소개합니다.
이 &는 중첩된 상태일 때 외부의 선택자를 참조할 수 있습니다.
짠, 부모선택자의 이름을 반복해서 쓸 필요없이 &
하나만으로 뚝딱 대체할 수 있습니다.
특히 부모선택자의 이름을 계속해서 가져다 쓰는 BEM 방법론에 찰떡이죠.
.accordion {
max-width: 600px;
margin: 4rem auto;
width: 90%;
font-family: "Raleway", sans-serif;
background: #f4f4f4;
&__copy {
display: none;
padding: 1rem 1.5rem 2rem 1.5rem;
color: gray;
line-height: 1.6;
font-size: 14px;
font-weight: 500;
&--open {
display: block;
}
}
}
컴파일된 결과와 비교해 보세요!
이는 자기 자신을 재선택할 때도 유용합니다. &:hover
나 & + p
처럼 스스로를 선택해서 작성할 수도 있죠.
button {
color: blue;
&:hover {
opacity: 0.5
}
&:disabled {
opacity: 0.3;
cursor: not-allowed;
}
&.isLoading {
color: green;
}
& + button {
margin-top: 10px;
}
};
&
가 컴파일되면서 부모 선택자로 치환되는 것이므로, & span
/ &span
/ &.span
은 각각 다르게 취급됩니다.
그럼 아래의 Sass 문이 어떻게 컴파일될지 느낌이 팍 오죠!
.hello {
& span {
color: blue;
}
&span {
color: green;
}
&.span {
color: purple;
}
}
답은 차례대로 ① .hello span ② .hellospan ③ .hello.span 입니다
SassMeister 에서 쳐보시면 금방 감이 잡힐 거예요 🤩
유의할 점 한 가지! &
선택자는 복합 선택자의 시작 부분에만 쓸 수 있습니다.
예를 들어 :not(&)
는 가능하지만 .item&
처럼 끝에 쓰는 건 불가능합니다.
또, @media 같은 at-rules 가 중첩되어 있으면 스타일 규칙이 그 안에 있도록 바꿔주기 때문에 쉽게 조건을 추가할 수 있어요.
3) 변수: 걔가 얘야
Sass에서는 $변수명: 값;
으로 변수를 선언해 사용할 수 있습니다.
우리가 지난 글에서 예제로 살펴봤던 것처럼 쓰면 됩니다.
변수에는 문자, 숫자, 불린, 컬러값, null 등 정말 다양한 값을 담을 수 있어요!
$width: 100rem;
$font: "Noto Sans KR";
$color: #000;
$darkMode: true;
$init: null;
TMI
이렇게 속성이나 변수 선언 오른쪽에 있는 값을 SassScript 라고 부릅니다.
값을 담는 데서 끝이 아니고 != 처럼 비교하거나 +/-/* 등의 산술을 할 수도 있고, 함수의 인자로 넘길 수도 있죠.
자세한 활용법은 투비 컨티뉴 🙌
또한 선언 위치에 따라 전역변수 또는 지역변수로 사용할 수도 있어요.
.header {
$var-header: '이 변수는 .header 내에서만 쓸 수 있어요!';
}
.body {
content: $var-header; //오류!
}
물론 CSS에서도 var(--변수명) 이라고 글로벌 변수를 쓸 수 있어요!
하지만 Sass의 변수는 CSS 변수와 조금 다릅니다.
- Sass의 변수는 컴파일되면서 사라집니다. CSS 파일에 보이지 않아요.
- Sass의 변수는 한 번에 단 하나의 값만 가집니다.
- Sass의 변수는 재할당 시 이전의 내용을 바꾸지 않습니다.
$var: 'nana';
.first { content:$var; } //nana
$var: 'like';
.second { content:$var; } //like
또, Sass 변수에서 하이픈(-)과 언더스코어(_)는 동일하게 취급됩니다.
따라서 $font-size와 $font_size는 완벽하게 동일합니다! 🤟
$font_size: 10px;
$font-size: 200px;
.underscore {
font-size: $font_size; //200px;
}
.hypen {
font-size: $font-size; //200px;
}
TMI
옛날에는 Sass 변수에 언더스코어만 쓸 수 있었으나 업데이트되면서 하이픈도 지원하게 됐다고 하네요!
마이그레이션을 쉽게 하기 위해서 둘을 같은 걸로 취급하는 모양입니다.
그렇다면 변수는 언제 쓰는 게 좋을까요? 그건 쓰는 사람 마음대로! ...긴 한데요,
변수가 난잡하면 그것 나름대로 보기 어려워져서 '쓸 만한 상황이다'라고 판단될 때 쓰는 게 좋겠죠.
- 값이 여러 곳에서 반복되거나
- 수정될 가능성이 높을 때 사용하는 것이 가장 좋겠습니다.
4) 보간: 슬쩍 끼워넣기!
변수를 font-size: $size;
와 같이 불러다 쓸 수 있다는 걸 배웠습니다.
그렇다면 CSS 속성값 안에 그대로 끼워넣는 것도 가능할까요?
$name: "cart";
.icon-cart {
background-image: url("/icons/$name.png");
}
/*
출력결과:
.icon-cart {
background-image: url("/icons/$name.png");
}
*/
의도한 거랑은 다르게 나왔네요. 저 이미지 주소 내에 $name을 끼워넣고 싶었는데 말이죠.. 머쓱...
아니면 이런 것도 가능할까요? position 을 변수로 주고 top: 50px 을 적용하고 싶습니다.
$position: top;
.header {
position: fixed;
$position: 50px;
}
/*
출력결과:
.header {
position: fixed;
}
(내 $position 어디 간 거야... 😿)
*/
넵, 문자열이나 셀렉터 등에 변수를 쓰려면 그냥은 안 되고 #{} 라는 보간(Interpolation)이 필요합니다.
방법은 변수를 #{}
로 감싸주기만 하면 됩니다!
$position: top;
$name: cart;
$height: 200px;
.header {
position: fixed;
#{$position}: 50px;
background-image: url("/icons/#{$name}.png");
width: calc(100vh - #{$height});
}
/*
출력결과:
.header {
position: fixed;
top: 50px; //야호 top을 인식했다!
background-image: url("/icons/cart.png"); //야호(2) cart를 인식했다!
width: calc(100vh - 200px);
}
*/
만약 CSS 변수에서 Sass 변수나 함수를 끌어다쓰고 싶다면 보간법을 사용합니다.
$color-accent: #0080ff;
:root {
--color-accent: #{$color-accent};
--color-accent-100: #{rgba($color-accent, 0.07)};
--color-accent-200: #{rgba($color-accent, 0.2)};
--color-accent-300: #{rgba($color-accent, 0.4)};
}
한 가지 짚고 넘어가면 좋은 점! 보간이 리턴하는 것은 따옴표가 없는 문자열(unquoted strings)입니다.
따라서 단위 사이에 끼워넣을 때는 보간을 쓰기보다는 아래와 같이 쓰는 걸 추천합니다.
$size: 100;
.main {
width: #{$size}rem; //Not recommend 😐
}
.footer {
width: #{$size} * 1rem; //Good 😊
}
이유는 변수에 단위가 잘못 들어갔을 때, 컴파일 과정에서 에러를 잡을 수 없기 때문입니다.
$size: 100px; //어이쿠! 모르고 px을 써버렸다!
.main {
width: #{$size}rem;
}
.footer {
width: #{$size} * 1rem;
}
/*
컴파일 결과:
.main { width: 100pxrem; }
.footer { //에러 }
*/
보간은 문자열을 리턴하므로 pxrem이란 요상한 단위가 튀어나오게 됩니다.
컴파일러 입장에선 문자열끼리 잘 있는 것이므로 딱히 에러를 내뱉지 않습니다. (다행히 브라우저는 이 단위를 무시하겠지만요)
하지만 100px * 1rem은 명확하게 단위가 맞지 않으니 개발단계에서 에러를 캐치하고 수정하는 것이 가능합니다.
또, 문자열을 감싼 따옴표는 보간으로 사용 시 컴파일 과정에서 사라집니다.
$var: "Nana";
.hello {
background-image: url('/images/#{$var}.png');
}
/*
출력결과:
.hello {
background-image: url("/images/Nana.png");
}
*/
5) 인라인 주석: 우리끼리만 보는 주석
CSS에서 주석은 /* */
형태로 사용했죠.
CSS 파일은 누구나 뜯어볼 수 있기 때문에 비밀스러운(?) 주석을 다는 것이 불가능합니다.
개발하다보면 개발에만 필요한 주석을 달아야할 때가 있는데 말이죠.
이런 불편함을 해소하고자 Sass에서는 //
형태로 인라인 주석을 사용할 수 있습니다.
인라인 주석은 어디든 끼워넣을 수 있고, 컴파일 과정에서 뿅 사라집니다.
6) 출력스타일: 어떤 스타일로 해드릴까요
Dart Sass는 두 가지의 출력 스타일을 제공합니다.
- expanded = 펼쳐주세요! (기본값)
- compressed = 압축해주세요!
compressed 옵션을 택하면 빈 여백을 가능한 제거하고 전체 스타일시트를 한 줄에 작성해 줍니다.
저번 글에서 플래그로 --watch 옵션을 껴넣었던 것처럼, --style 옵션으로 출력 스타일을 제어할 수 있습니다.
터미널에서 sass 명령을 내릴 때 아래와 같이 입력해 보세요.
sass --style=compressed style.scss style.css
그럼 이렇게 꽉꽉 압축시킨 CSS 파일을 얻을 수 있습니다! 알아서 압축도 해주고 좋네요 😉
compressed 옵션일 때는 일반 CSS 주석 /* 주석 */
도 제거됩니다.
하지만 !
를 붙여 강조하면 압축모드에서도 표시되므로, 중요한 정보는 /*! 중요한 주석 */
형태로 남길 수 있습니다.
에필로그
CSS 작성을 좀 더 편하게 해줄 몇 가지 Sass 문법에 대해 알아봤습니다. 역시 편한 게 최고쥬
다음 글은 mixin, extend, 모듈화처럼 쪼개서 여기저기 가져다쓰는 법에 대해 써보려고 합니다.
글 마무리가 제일 어렵네요... 아무튼 긴 스크롤 함께해주셔서 감사합니다 🤗