=== Prologue ===
지난 포스팅에서 변수와 믹스인에 대해 알아봤다.
포스팅 이후 새 작업을 시작했을 때 변수를 써서 작업해봤었는데 (네스팅만 쓰고 있었던지라)
사수님께서 알아보시고 좋아하셨다.
변수랑 믹스인까지만 쓰더라도 작업 속도가 훨씬 빨라질 거라고 말해주셨는데
정말 그런 것 같기도 하고!! 우선 오늘은 네스팅에 대해 더 자세히 알아보자.
[Sass의 기능]
Sass는 다음과 같은 기능을 가진다.
1 변수
2 네스팅
- 루프
- 인수
- 혼합
3 mixin
4 실렉터 상속
==== Mission ====
- 네스팅(Neseting)에 대해 알아보자
- 네스팅을 할 시 유용한 함수(at-root)도 익혀본다.
- 예제에 포함된 selector.unify() function 함수도 익혀보자.
=== description ===
2. 네스팅 = 중첩
선언을 중첩(nesting) 하는 것
CSS로 파일 작성 시 클래스를 일일이 지정해 주지 않는 이상 부모 자식 간의 관계를 따라 코드를 작성하게 된다.
근데 그때마다 부모 클래스를 써주고 자식 or 자손의 클래스명을 쓰게 되는데 코드가 많아지면 많아질수록 복잡해지고 보기 힘들어지게 된다. Sass를 쓰게 되면 부모 셀렉터를 쓰는 것을 줄여주고 HMTL 구조에 따라서 눈에 보기 쉽게 코드를 작성할 수 있다.
밑에 예시를 살펴보자
==== detail progress ====
nav안에 있는 ul, li, a를 [CSS]에서는 이렇게 썼다. nav를 세 번 쓰고 후손셀렉터를 일일이 써 주었다.
[CSS]
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav li {
display: inline-block;
}
nav a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
SCSS or Sass는 네스팅 방식에 따라서
부모 셀렉터를 한번 써주고 그 안에 {} 중괄호를 넣어서
구조를 (부모 자식관계) 구분시켜 써주면 된다.
** 너무 깊은 nesting은 가독성을 나쁘게 하고 셀렉터를 복잡하게 만든다.
[SCSS]
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
[SASS]
nav
ul
margin: 0
padding: 0
list-style: none
li
display: inline-block
a
display: block
padding: 6px 12px
text-decoration: none
Ampersand(상위 선택자 참조) : &
부모 요소를 참조하는 셀렉터
만약 부모 요소의 참조가 필요한 경우 &을 이용해서 그 부모의 하위 { }에 써주면 된다.
:hover ::before, ::after 등이 그 예이다.
css에서는 요소 옆에 :hover를 써주면 되지만
SCSS에선 &를 사용한다. 이후에는 동일하다.
[SCSS]
@mixin button-base() {
@include typography(button);
@include ripple-surface;
@include ripple-radius-bounded;
display: inline-flex;
position: relative;
height: $button-height;
border: none;
vertical-align: middle;
&:hover { cursor: pointer; }
&:disabled {
color: $mdc-button-disabled-ink-color;
cursor: default;
pointer-events: none;
}
}
at root (중첩에서 벗어나기)
부모 선택자에 중첩되어 css를 작성한다. (구조에 맞춰서)
그런데 해당 선택자가 부모에 선택되지 않고 독립적으로 써야 할 때 @at-root를 써주면 좋다.
The @at-root rule is usually written @at-root <selector> { ... } and causes everything within it to be emitted at the root of the document instead of using the normal nesting.
예제를 살펴보자.
앞 포스팅에서 @mixins 함수를 썼었는데 해당 예제에 포함되어 있다.
잠깐 예제에 해당되는 selector.unify() 함수도 살펴보자.
selector.unify() function ===> 두 선택자를 합칠 수 있다. 예를 들면
selector1 과 selector2자리에 selector가 중첩되어있으면 그 selector를 통합(unify) 해주는 함수이다. 서로 같은 셀렉터(클래스명) 을 찾아서 같으면 하나를 상쇄시키고 중첩시켜준다.
selector.unify($selector1, $selector2)
selector-unify($selector1, $selector2) //=> selector | null
@debug selector.unify("a", ".disabled"); // a.disabled
@debug selector.unify("a.disabled", "a.outgoing"); // a.disabled.outgoing
@debug selector.unify("a", "h1"); // null
@debug selector.unify(".warning a", "main a"); // .warning main a, main .warning a
이제 본격 at-root에 관한 예제
아우터 선택자('. wraapper)와 요소 선택자('. field)를 매치하는 코드를 작성한다고 할 때, selector.unify() function와 mixin 함수를 이용해 작성할 수 있다.
1. mixin 함수로 변수를 만들고,
2.. wrapper. field에 mixin을 호출시킨다. (불러온다)
mixin unify-parent라는 변수에는 at-root가 포함되어 클래스 명이 $child 인 것과는 unify 하지만,
3. 중첩(nesting) 하지 않고, 독립적으로 쓰기를 원한다.
4. 그러면 해당 $child에 써진 클래스들은 하위 메뉴로 가는 게 아니라 독립적으로 작성이 된다.
[CSS]로 도출(컴파일)되는 값을 살펴보며 비교해 보면 이해가 될 것이다.
독립적으로. field 클래스는 unifiy-selector가 된 것을 볼 수 있다.
[SCSS]
@use "sass:selector";
@mixin unify-parent($child) {
@at-root #{selector.unify(&, $child)} {
@content;
}
}
.wrapper .field {
@include unify-parent("input") {
/* ... */
}
@include unify-parent("select") {
/* ... */
}
}
[SASS]
@use "sass:selector"
@mixin unify-parent($child)
@at-root #{selector.unify(&, $child)}
@content
.wrapper .field
@include unify-parent("input")
/* ... */
@include unify-parent("select")
/* ... */
[CSS]
.wrapper input.field {
/* ... */
}
.wrapper select.field {
/* ... */
}
본격 at-root에 관한 예제 02 **** 추후 알아보기 쉬운 예제를 업로드할 예정!!
미디어 쿼리 문법 안에서도 at-root를 유용하게 사용할 수 있다.
스타일 처리를 예외 적용시킬 수 있게 된다는 말이다.
반응형 작업을 하게 될 때 주로 미디어 쿼리를 쓰는데,
at-root를 쓰면 예외를 처리할 수 있게 되는 것
@at-root (with: <rules...>) { ... } or @at-root (without: <rules...>) { ... }
미디어 쿼리 특징과 같이 (원하는 영역) 구문을 사용할지 안 할지를 with: 또는 without: 을 써서 구분해 줘야 한다.
On its own, @at-root only gets rid of style rules. Any at-rules like @media or @supports will be left in. If this isn’t what you want, though, you can control exactly what it includes or includes using syntax like media query features, written @at-root (with: <rules...>) { ... } or @at-root (without: <rules...>) { ... }. The (without: ...) query tells Sass which rules should be excluded; the (with: ...) query excludes all rules except those that are listed.
예제를 보면,
[SCSS]
@media print {
.page {
width: 8in;
@at-root (without: media) {
color: #111;
}
@at-root (with: rule) {
font-size: 1.2em;
}
}
}
[SASS]
@media print
.page
width: 8in
@at-root (without: media)
color: #111
@at-root (with: rule)
font-size: 1.2em
without: media를 써 media 안에서 부모의 상속을 받지 않고 독립적으로 작성되었고,
마찬가지로 at-root(with: rule) 도 원하는 영역을 media 쿼리문 밖으로 컴파일할 수 있도록 해준다.
[CSS]
@media print {
.page {
width: 8in;
}
}
.page {
color: #111;
}
.page {
font-size: 1.2em;
}
==== Result ====
알면 알수록 알 것 같기도 하고,, 아직은 조금 헷갈리는 부분이 있다.
하지만 공부할수록 정말 편리한 기능들이 많은 것 같다.
업무에도 적용할 수 있는 날이 머지않았다.!!
==== Reference====
https://sass-lang.com/documentation/at-rules/at-root
https://mesonia.tistory.com/45
'FRONTEND > style.css' 카테고리의 다른 글
[SASS] SASS 문법01 - 변수(Variables)와 믹스인(Mixins) (0) | 2021.07.21 |
---|---|
[SASS] SASS의 개념과 확장 프로그램 설치 (0) | 2021.07.19 |
[css] ul 태그 list-style 없이 li 목록 앞 ▶ 적용 시키기 (0) | 2021.06.21 |