본문으로 바로가기

LESS Extend

category StyleSheet/LESS 2016. 9. 29. 09:56

Extends in LESS

이 글에서는 LESS에서 Extend 문법에 대해 알아봅니다.

extend는 참조하는 내용과 일치하는 곳에 선택자를 병합해 주는 의사 클래스입니다.





Extend

:extend 인자로 전달된 선택자를 :extend 가 선언된 블록(이용되는 선택자)을 확장하여 적용할 수 있도록 해줍니다.(CSS를 확장하지는 않습니다)

다음의 코드를 살펴봅니다.

less
nav ul {
	&:extend(.extend-demo); // nav ul 을 확장한다
	background: blue;
}
.extend-demo {
	color: red;
}
컴파일된 css
nav ul {
  background: blue;
}
.extend-demo,
nav ul {
  color: red;
}



Extend Syntax

선택자는 선택자 또는 룰셋 안에 작성할 수 있습니다.

아래 두 표현식은 같은 동작을 합니다.

less
.a:extend(.b) {}

// 위 구문은 아래 구문과 같은 동작을 한다
.a {
	&:extend(.b);
}


예제 코드를 살펴봅니다.

less
.a:extend(.b) {}

.b {
	line-height: 1;
	text-align: center;
}
컴파일된 css
.b,
.a {
  line-height: 1;
  text-align: center;
}


아래와 같이 선택적으로 키워드 all 을 사용할 수 있습니다.

less
.c:extend(.d all) {
	// all 키워드를 사용하면  ".x.d" 또는 ".d.x" 로 출력됩니다.
}

다음의 예제를 살펴봅니다.

less
.mymenu:extend(.navbar .menu all) {
	line-height: 1;
}

.navbar .menu.multiClass {
	padding: 10px;
}
css
.mymenu {
  line-height: 1;
}
.navbar .menu.multiClass,
.mymenu.multiClass {
  padding: 10px;
}


아래와 같이 하나이상의 선택자를 확장하기 위해 콤마(,)를 사용할 수 있습니다.

less
.e:extend(.f) {}
.e:extend(.g) {}

// 위의 표현식을 아래와 같이 표현할 수 있습니다.
.e:extend(.f, .g) {}

다음의 예제를 살펴봅니다.

less
.e:extend(.f, .g) {}

.f {
	margin: 10px;
}
.g {
	text-align: center;
}
컴파일된 css
.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는 마지막에 있어야 한다.


less
.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;
}
컴파일된 css
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) 문법을 사용함으로써 룰셋 몸통에 작성할 수 있습니다.

룰셋 몸통안에 다음과 같이 합니다.

less
pre:hover,
.some-class {
	&:extend(div pre);
}

div pre {
	text-align: left;
}
컴파일된 css
div pre,
pre:hover,
.some-class {
  text-align: left;
}

다음의 용법은 위에서 사용된 방법과 같습니다.

less
pre:hover:extend(div pre),
.some-class:extend(div pre) {}



Extending Nested Selectors(중첩된 선택자 확장하기)

중첩된 선택자에서 extend를 다음과 같이 사용할 수 있습니다.

less
.bucket {
	tr { // 중첩된 타켓 선택자
		color: blue;
	}
}
.some-class:extend(.bucket tr) {}
컴파일된 css
.bucket tr,
.some-class {
  color: blue;
}


& 부모 선택자를 이용하여 다음과 같이 사용할 수도 있습니다.

less
.bucket {
	tr & { // parent selector
		color: blue;
	}
}
.some-class:extend(tr .bucket) {}
컴파일된 css
tr .bucket,
.some-class {
  color: blue;
}



Exact Matching with Extend(extend 정확히 매칭시키기)

extend 에 전달한 선택자와 정확히 일치시키지 않으면 extend를 사용할 수 없습니다.

less
.test:extend(.class) {}

// 아래와 같이 extend 의 파라미터를 정확히 일치시키지 않으면 확장하지 않는다
.a.class,
.class.a,
.class > .a {
	color: blue;
}
컴파일된 css
.a.class,
.class.a,
.class > .a {
  color: blue;
}


*.class.class는 동등하지만 extend에서는 확장되지 않습니다.

less
*.class {
	color: blue;
}
.noStar:extend(.class) {}
컴파일된 css
*.class {
  color: blue;
}

선택자 link:hover:visitedlink:visited:hover는 같은 요소를 정의하지만 extend 에서는 다르게 다룹니다

아래와 같이 extend를 일치시키지 않으면 확장되지 않습니다.

less
link:hover:visited {
	color: blue;
}
.selector:extend(link:visited:hover) {}
컴파일된 css
link:hover:visited {
  color: blue;
}


아래처럼 정확히 일치시켜야만 올바르게 확장될 것입니다.

less
link:visited:hover {
	color: blue;
}
.selector:extend(link:visited:hover) {}
컴파일된 css
link:visited:hover,
.selector {
  color: blue;
}



nth Expression(n번째 표현식)

nth 를 사용할 때에도 정확히 일치시켜야만 확장됩니다.

1n+3 and n+3 는 동등한 표현이지만 extend는 정확히 일치시키지 않으면 확장하지 않습니다.

다음은 extend를 일치시키지 않은 코드로 인해 기대하지 않은 결과가 나타날 것입니다.

less
:nth-child(1n+3) {
	color: blue;
}
.child:extend(:nth-child(n+3)) {}
컴파일된 css
:nth-child(1n+3) {
  color: blue;
}


다음처럼 일치시켜야 기대했던 결과를 얻을 수 있습니다.

less
:nth-child(n+3) {
	color: blue;
}
.child:extend(:nth-child(n+3)) {}
컴파일된 css
:nth-child(n+3),
.child {
  color: blue;
}


다음의 타입은 정확히 일치시키지 않아도 올바르게 확장됩니다.

less
[title='identifier'] {
	color: red;
}

.noQuote:extend([title=identifier]) {}
컴파일된 css
[title='identifier'],
.noQuote {
  color: red;
}



Extend "all" (extend에 all 키워드 사용하기)

사용자는 extend 파라미터의 마지막에 all 키워드를 작성할 수 있고 또 다른 선택자 일부분으로 매칭시킬 수 있습니다.

선택자는 복사되어 셀렉터에 일치하는 부분을 새로운 선택자로 만들어 확장하여 대체합니다

less
.a.b.test, // extend 파라미터 일치하는 부분인 .test 가 replacement로 확장,대체된다
.test.c { // extend 파라미터 일치하는 부분인 .test 가 replacement로 확장,대체된다
	color: orange;
}
.test {
	&:hover {
		color: green;
	}
}

.replacement:extend(.test all) {}
컴파일된 css
.a.b.test,
.test.c,
.a.b.replacement,
.replacement.c {
  color: orange;
}
.test:hover,
.replacement:hover {
  color: green;
}



Selector Interpolation with Extend(확장과 선택자 보간법)

extend 는 변수로 선택자를 일치시킬 수 없습니다.

선택자에 변수가 포함되어 있는 경우 extend는 그것을 무시할 것입니다.

아래와 같이 사용하는 경우는 확장되지 않습니다.

less
@variable: .bucket;
@{variable} { // 이와 같은 보간 선택자 사용시 확장되지 않는다
	color: blue;
}
.some-class:extend(.bucket) {}
컴파일된 css
.bucket {
  color: blue;
}


다음과 같이 사용해도 확장되지 않습니다.

less
.bucket {
	color: blue;
}
.some-class:extend(@{variable}) {} // 보간 선택자는 아무것도 일치시키지 않는다
@variable: .bucket;
컴파일된 css
.bucket {
  color: blue;
}


하지만 :extend앞에 보간선택자를 사용하면 기대한 결과값으로 확장됩니다. 다음과 같이 :

less
.bucket {
	color: blue;
}
@{variable}:extend(.bucket) {}
@variable: .selector;
컴파일된 css
.bucket,
.selector {
  color: blue;
}



Scoping / Extend Inside @media(범위지정과 미디어쿼리 내부 확장하기)

미디어 내부에 선언된 extend는 같은 미디어 선언 내부의 선택자만을 일치시켜야 동작합니다.

less
@media print {
	.screenClass:extend(.selector) {} // @media 내부의 extend
	.selector { // 같은 미디어 내부의 것을  일치하여 확장시킨다
		color: black;
	}
}
.selector { // 같은 미디어 내부에서 사옹하지 않기 때문에 이 룰셋은 확장하지 않는다
	color: red;
}
@media screen {
	.selector {  // 또 다른 미디어 내부의 롤셋에 extend를 사용하지 않고 있기 때문에 확장하지 않는다.
		color: blue;
	}
}
컴파일된 css
@media print {
  .selector,
  .screenClass {
    color: black;
  }
}
.selector {
  color: red;
}
@media screen {
  .selector {
    color: blue;
  }
}


미디어 선언 내부의 작성된 extend는 내부의 중첩 선언 선택자를 일치하지 않습니다.

less
@media screen {
	.screenClass:extend(.selector) {} // 미디어 내부의 extend
	@media (min-width: 1023px) {
		.selector {  // 중첩된 미디어 내부의 선택자는 확장되지 않는다.
			color: blue;
		}
	}
}
컴파일된 css
@media screen {
}
@media screen and (min-width: 1023px) {
  .selector {
    color: blue;
  }
}


최상단의 전역스코프에서 작성된 extend는 중첩된 미디어 내부 선택자를 포함한 모든 선택자와 일치시켜 확장되어 집니다. 다음과 같이 :

less
@media screen {
	.selector {  // 중첩된 미디어 내부의 룰셋 (최상단에서 동작한다)
		color: blue;
	}
	@media (min-width: 1023px) {
		.selector {  // 중첩된 미디어 내부의 룰셋 (최상단에서 동작한다)
			color: blue;
		}
	}
}

.topLevel:extend(.selector) {} // 최상위인 전역스코프에서 extend 사용시 모든 선택자에 대해 일치시킨다.
컴파일된 css
@media screen {
  .selector,
  .topLevel {
    color: blue;
  }
}
@media screen and (min-width: 1023px) {
  .selector,
  .topLevel {
    color: blue;
  }
}




Reducing CSS Size(CSS 용량 줄이기)

믹스인은 셀렉터 안의 모든 속성을 복사하여 불필요한 중복을 야기시킬 수 있습니다.

그래서 사용자는 믹스인 대신에 extend를 사용하시기 바랍니다.

이는 보다 적은 CSS를 생성하여 사용할 수 있습니다.

만약 믹스인 사용을 할 때 아래와 같이 작성한다면 불필요한 CSS를 생성하게 될 것입니다.

less
.my-inline-block() {
	display: inline-block;
	font-size: 0;
}
/* 중복 코드 발생 */
.thing1 {
	.my-inline-block;
}
.thing2 {
	.my-inline-block;
}
컴파일된 css
/* 중복 코드 발생 */
.thing1 {
  display: inline-block;
  font-size: 0;
}
.thing2 {
  display: inline-block;
  font-size: 0;
}


extend를 사용하면 아래처럼 보다 적은 CSS를 생성하게 될 것입니다.

less
.my-inline-block {
	display: inline-block;
	font-size: 0;
}
.thing1 {
	&:extend(.my-inline-block);
}
.thing2 {
	&:extend(.my-inline-block);
}
컴파일된 css
.my-inline-block,
.thing1,
.thing2 {
  display: inline-block;
  font-size: 0;
}



Combining Styles / A More Advanced Mixin(스타일 결합하기/고급 믹스인)

다음의 사용 사례는 믹스인에 대한 대안이 될 수 있습니다.

믹스인은 단순 선택자로만 사용할 수 있기 때문에 HTML에 서로 다른 두 블럭이 있다면 사용자는 두 블럭, 모두에 동일한 스타일을 적용하기 위해 두 영역을 연결시키기 위해 확장하는 것이 좋을 것입니다.

다음의 예를 살펴보겠습니다.

less
li.list > a {
	background-color: #fff;
	padding-left: 5px;
}
button.list-style {
	// 또 다른 블럭에 li.list > a 에 정의된 스타일을 동일하기 사용하기 위해 확장한다
	&:extend(li.list > a);
}
컴파일된 css
li.list > a,
button.list-style {
  background-color: #fff;
  padding-left: 5px;
}



Jaehee's WebClub


'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