Extends in LESS
이 글에서는 LESS에서 Extend 문법에 대해 알아봅니다.
extend
는 참조하는 내용과 일치하는 곳에 선택자를 병합해 주는 의사 클래스입니다.
Extend
:extend
인자로 전달된 선택자를 :extend 가 선언된 블록(이용되는 선택자)을 확장하여 적용할 수 있도록 해줍니다.(CSS를 확장하지는 않습니다)
다음의 코드를 살펴봅니다.
nav ul {
&:extend(.extend-demo); // nav ul 을 확장한다
background: blue;
}
.extend-demo {
color: red;
}
nav ul {
background: blue;
}
.extend-demo,
nav ul {
color: red;
}
Extend Syntax
선택자는 선택자 또는 룰셋 안에 작성할 수 있습니다.
아래 두 표현식은 같은 동작을 합니다.
.a:extend(.b) {}
// 위 구문은 아래 구문과 같은 동작을 한다
.a {
&:extend(.b);
}
예제 코드를 살펴봅니다.
.a:extend(.b) {}
.b {
line-height: 1;
text-align: center;
}
.b,
.a {
line-height: 1;
text-align: center;
}
아래와 같이 선택적으로 키워드 all
을 사용할 수 있습니다.
.c:extend(.d all) {
// all 키워드를 사용하면 ".x.d" 또는 ".d.x" 로 출력됩니다.
}
다음의 예제를 살펴봅니다.
.mymenu:extend(.navbar .menu all) {
line-height: 1;
}
.navbar .menu.multiClass {
padding: 10px;
}
.mymenu {
line-height: 1;
}
.navbar .menu.multiClass,
.mymenu.multiClass {
padding: 10px;
}
아래와 같이 하나이상의 선택자를 확장하기 위해 콤마(,)를 사용할 수 있습니다.
.e:extend(.f) {}
.e:extend(.g) {}
// 위의 표현식을 아래와 같이 표현할 수 있습니다.
.e:extend(.f, .g) {}
다음의 예제를 살펴봅니다.
.e:extend(.f, .g) {}
.f {
margin: 10px;
}
.g {
text-align: center;
}
.f,
.e {
margin: 10px;
}
.g,
.e {
text-align: center;
}
Extend Attached to Selector(선택자 뒤에 extend 사용하기)
extend는 선택자 뒤에 작성할 수 있고 이것은 일반적인 의사클래스처럼 보입니다.
선택자 뒤에 extend를 사용하는 용법은 다음과 같습니다.
pre:hover:extend(div pre)
- 선택자와 extend 사이에 스페이스를 허용한다 :
pre:hover :extend(div pre)
- 멀티 extend 사용이 가능하다 :
pre:hover:extend(div pre):extend(.bucket tr)
- 멀티 extend(위와 같음) :
pre:hover:extend(div pre, .bucket tr)
- 이 용법은 허용되지 않는다 :
pre:hover:extend(div pre).nth-child(odd)
* extend는 마지막에 있어야 한다.
.big-division,
.big-bag:hover:extend(div pre):extend(.bucket tr),
.big-bucket:extend(.bucket) {
// body
}
div pre {
background-color: #fff;
}
.bucket tr{
text-align: center;
}
.bucket {
line-height: 1;
}
div pre,
.big-bag:hover {
background-color: #fff;
}
.bucket tr,
.big-bag:hover {
text-align: center;
}
.bucket,
.big-bucket {
line-height: 1;
}
Extend Inside Ruleset(룰셋 내부에 extend 사용하기)
&:extend(selector)
문법을 사용함으로써 룰셋 몸통에 작성할 수 있습니다.
룰셋 몸통안에 다음과 같이 합니다.
pre:hover,
.some-class {
&:extend(div pre);
}
div pre {
text-align: left;
}
div pre,
pre:hover,
.some-class {
text-align: left;
}
다음의 용법은 위에서 사용된 방법과 같습니다.
pre:hover:extend(div pre),
.some-class:extend(div pre) {}
Extending Nested Selectors(중첩된 선택자 확장하기)
중첩된 선택자에서 extend를 다음과 같이 사용할 수 있습니다.
.bucket {
tr { // 중첩된 타켓 선택자
color: blue;
}
}
.some-class:extend(.bucket tr) {}
.bucket tr,
.some-class {
color: blue;
}
&
부모 선택자를 이용하여 다음과 같이 사용할 수도 있습니다.
.bucket {
tr & { // parent selector
color: blue;
}
}
.some-class:extend(tr .bucket) {}
tr .bucket,
.some-class {
color: blue;
}
Exact Matching with Extend(extend 정확히 매칭시키기)
extend 에 전달한 선택자와 정확히 일치시키지 않으면 extend를 사용할 수 없습니다.
.test:extend(.class) {}
// 아래와 같이 extend 의 파라미터를 정확히 일치시키지 않으면 확장하지 않는다
.a.class,
.class.a,
.class > .a {
color: blue;
}
.a.class,
.class.a,
.class > .a {
color: blue;
}
*.class
와 .class
는 동등하지만 extend에서는 확장되지 않습니다.
*.class {
color: blue;
}
.noStar:extend(.class) {}
*.class {
color: blue;
}
선택자 link:hover:visited
와 link:visited:hover
는 같은 요소를 정의하지만 extend 에서는 다르게 다룹니다
아래와 같이 extend를 일치시키지 않으면 확장되지 않습니다.
link:hover:visited {
color: blue;
}
.selector:extend(link:visited:hover) {}
link:hover:visited {
color: blue;
}
아래처럼 정확히 일치시켜야만 올바르게 확장될 것입니다.
link:visited:hover {
color: blue;
}
.selector:extend(link:visited:hover) {}
link:visited:hover,
.selector {
color: blue;
}
nth Expression(n번째 표현식)
nth 를 사용할 때에도 정확히 일치시켜야만 확장됩니다.
1n+3 and n+3 는 동등한 표현이지만 extend는 정확히 일치시키지 않으면 확장하지 않습니다.
다음은 extend를 일치시키지 않은 코드로 인해 기대하지 않은 결과가 나타날 것입니다.
:nth-child(1n+3) {
color: blue;
}
.child:extend(:nth-child(n+3)) {}
:nth-child(1n+3) {
color: blue;
}
다음처럼 일치시켜야 기대했던 결과를 얻을 수 있습니다.
:nth-child(n+3) {
color: blue;
}
.child:extend(:nth-child(n+3)) {}
:nth-child(n+3),
.child {
color: blue;
}
다음의 타입은 정확히 일치시키지 않아도 올바르게 확장됩니다.
[title='identifier'] {
color: red;
}
.noQuote:extend([title=identifier]) {}
[title='identifier'],
.noQuote {
color: red;
}
Extend "all" (extend에 all 키워드 사용하기)
사용자는 extend 파라미터의 마지막에 all 키워드를 작성할 수 있고 또 다른 선택자 일부분으로 매칭시킬 수 있습니다.
선택자는 복사되어 셀렉터에 일치하는 부분을 새로운 선택자로 만들어 확장하여 대체합니다
.a.b.test, // extend 파라미터 일치하는 부분인 .test 가 replacement로 확장,대체된다
.test.c { // extend 파라미터 일치하는 부분인 .test 가 replacement로 확장,대체된다
color: orange;
}
.test {
&:hover {
color: green;
}
}
.replacement:extend(.test all) {}
.a.b.test,
.test.c,
.a.b.replacement,
.replacement.c {
color: orange;
}
.test:hover,
.replacement:hover {
color: green;
}
Selector Interpolation with Extend(확장과 선택자 보간법)
extend 는 변수로 선택자를 일치시킬 수 없습니다.
선택자에 변수가 포함되어 있는 경우 extend는 그것을 무시할 것입니다.
아래와 같이 사용하는 경우는 확장되지 않습니다.
@variable: .bucket;
@{variable} { // 이와 같은 보간 선택자 사용시 확장되지 않는다
color: blue;
}
.some-class:extend(.bucket) {}
.bucket {
color: blue;
}
다음과 같이 사용해도 확장되지 않습니다.
.bucket {
color: blue;
}
.some-class:extend(@{variable}) {} // 보간 선택자는 아무것도 일치시키지 않는다
@variable: .bucket;
.bucket {
color: blue;
}
하지만 :extend
앞에 보간선택자를 사용하면 기대한 결과값으로 확장됩니다. 다음과 같이 :
.bucket {
color: blue;
}
@{variable}:extend(.bucket) {}
@variable: .selector;
.bucket,
.selector {
color: blue;
}
Scoping / Extend Inside @media(범위지정과 미디어쿼리 내부 확장하기)
미디어 내부에 선언된 extend는 같은 미디어 선언 내부의 선택자만을 일치시켜야 동작합니다.
@media print {
.screenClass:extend(.selector) {} // @media 내부의 extend
.selector { // 같은 미디어 내부의 것을 일치하여 확장시킨다
color: black;
}
}
.selector { // 같은 미디어 내부에서 사옹하지 않기 때문에 이 룰셋은 확장하지 않는다
color: red;
}
@media screen {
.selector { // 또 다른 미디어 내부의 롤셋에 extend를 사용하지 않고 있기 때문에 확장하지 않는다.
color: blue;
}
}
@media print {
.selector,
.screenClass {
color: black;
}
}
.selector {
color: red;
}
@media screen {
.selector {
color: blue;
}
}
미디어 선언 내부의 작성된 extend는 내부의 중첩 선언 선택자를 일치하지 않습니다.
@media screen {
.screenClass:extend(.selector) {} // 미디어 내부의 extend
@media (min-width: 1023px) {
.selector { // 중첩된 미디어 내부의 선택자는 확장되지 않는다.
color: blue;
}
}
}
@media screen {
}
@media screen and (min-width: 1023px) {
.selector {
color: blue;
}
}
최상단의 전역스코프에서 작성된 extend는 중첩된 미디어 내부 선택자를 포함한 모든 선택자와 일치시켜 확장되어 집니다. 다음과 같이 :
@media screen {
.selector { // 중첩된 미디어 내부의 룰셋 (최상단에서 동작한다)
color: blue;
}
@media (min-width: 1023px) {
.selector { // 중첩된 미디어 내부의 룰셋 (최상단에서 동작한다)
color: blue;
}
}
}
.topLevel:extend(.selector) {} // 최상위인 전역스코프에서 extend 사용시 모든 선택자에 대해 일치시킨다.
@media screen {
.selector,
.topLevel {
color: blue;
}
}
@media screen and (min-width: 1023px) {
.selector,
.topLevel {
color: blue;
}
}
Reducing CSS Size(CSS 용량 줄이기)
믹스인은 셀렉터 안의 모든 속성을 복사하여 불필요한 중복을 야기시킬 수 있습니다.
그래서 사용자는 믹스인 대신에 extend를 사용하시기 바랍니다.
이는 보다 적은 CSS를 생성하여 사용할 수 있습니다.
만약 믹스인 사용을 할 때 아래와 같이 작성한다면 불필요한 CSS를 생성하게 될 것입니다.
.my-inline-block() {
display: inline-block;
font-size: 0;
}
/* 중복 코드 발생 */
.thing1 {
.my-inline-block;
}
.thing2 {
.my-inline-block;
}
/* 중복 코드 발생 */
.thing1 {
display: inline-block;
font-size: 0;
}
.thing2 {
display: inline-block;
font-size: 0;
}
extend
를 사용하면 아래처럼 보다 적은 CSS를 생성하게 될 것입니다.
.my-inline-block {
display: inline-block;
font-size: 0;
}
.thing1 {
&:extend(.my-inline-block);
}
.thing2 {
&:extend(.my-inline-block);
}
.my-inline-block,
.thing1,
.thing2 {
display: inline-block;
font-size: 0;
}
Combining Styles / A More Advanced Mixin(스타일 결합하기/고급 믹스인)
다음의 사용 사례는 믹스인에 대한 대안이 될 수 있습니다.
믹스인은 단순 선택자로만 사용할 수 있기 때문에 HTML에 서로 다른 두 블럭이 있다면 사용자는 두 블럭, 모두에 동일한 스타일을 적용하기 위해 두 영역을 연결시키기 위해 확장하는 것이 좋을 것입니다.
다음의 예를 살펴보겠습니다.
li.list > a {
background-color: #fff;
padding-left: 5px;
}
button.list-style {
// 또 다른 블럭에 li.list > a 에 정의된 스타일을 동일하기 사용하기 위해 확장한다
&:extend(li.list > a);
}
li.list > a,
button.list-style {
background-color: #fff;
padding-left: 5px;
}
'StyleSheet > LESS' 카테고리의 다른 글
Import Directives & Options (0) | 2016.09.29 |
---|---|
LESS Parent Selector(&) (0) | 2016.09.29 |
Mixins as Functions & Passing Rulesets to Mixins (0) | 2016.09.29 |
LESS Parametric Mixins (0) | 2016.09.29 |
LESS 변수 & 믹스인(Mixins) (2) | 2016.09.29 |