読者です 読者をやめる 読者になる 読者になる

S.F. Page

Programming,Music,etc...

LESS - extendの書き方と@import (reference)

Web Bootstrap ブログ Boost

ブログテーマをBootstrapベースでカスタマイズしている。
今日はLESSの知識を深めるためにLanguage Features | Less.jsを読んでいたのだけれども、extendの書き方や@importも機能が拡張されていることを知った。日本語のLESSの情報はこの辺りアップデートされてないようなので、ちょっと気になる部分を書いておくことにする。

extendの書き方

オブジェクト指向言語風な書き方や多重継承もできることがわかった。

.btn-test {
    text-align:center;
    border:1px solid gray;
    color:black;
    &:hover {
        background-color:red;
    }
}

.btn-test2 {
    background:white;
}

// mixin
.btn-mixin {
    .btn-test;
}

// extend よく知られている書き方
.btn-extend {
    &:extend(.btn-test all);
}

// extend 自然な感じの書き方
.btn-extend2 :extend(.btn-test all){}

// extend 多重継承
.btn-extend3 :extend(.btn-test all,.btn-test2){}

結果は下記の通り

.btn-test,
.btn-extend,
.btn-extend2,
.btn-extend3 {
  text-align: center;
  border: 1px solid gray;
  color: black;
}
.btn-test:hover,
.btn-extend:hover,
.btn-extend2:hover,
.btn-extend3:hover {
  background-color: red;
}
.btn-test2,
.btn-extend3 {
  background: white;
}
.btn-mixin {
  text-align: center;
  border: 1px solid gray;
  color: black;
}
.btn-mixin:hover {
  background-color: red;
}

@import (reference)

@import (reference) はすごい。Bootstrapは巨大なライブラリなのでそのまま@importし、コンパイルするととても巨大なCSSファイルになってしまい、はてなブログのCSSファイルの容量制限に引っかかってしまう。なのでuncss等を使用して不要なCSS定義を削る必要があるとのことだったのだが、@import (reference) '(bootstrap.lessのURL)';とすると、継承やmixinした部分だけライブラリからインポートされ、展開されるのだ。
例えば下記のように書くとすると、.btn.bt-defaultのコードがbootstrap.lessから取り出され、展開される。

@import (reference) "bootstrap/less/bootstrap.less";

.btn-test {
    .btn;
    .btn-default;
}

.btn-extend :extend(.btn all,.btn-default all){}

結果は以下のとおりだ。

@media print {
  .btn-extend > .caret,
  .dropup > .btn-extend > .caret {
    border-top-color: #000 !important;
  }
}
.form-horizontal .form-group-sm .form-control {
  height: 30px;
  padding: 5px 10px;
  font-size: 12px;
  line-height: 1.5;
  border-radius: 3px;
}
.form-horizontal .form-group-lg .form-control {
  height: 46px;
  padding: 10px 16px;
  font-size: 18px;
  line-height: 1.33;
  border-radius: 6px;
}
.btn-extend {
  display: inline-block;
  margin-bottom: 0;
  font-weight: normal;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
  background-image: none;
  border: 1px solid transparent;
  white-space: nowrap;
  padding: 6px 12px;
  font-size: 14px;
  line-height: 1.42857143;
  border-radius: 4px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.btn-extend:focus,
.btn-extend:active:focus,
.btn-extend.active:focus {
  outline: thin dotted;
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}
.btn-extend:hover,
.btn-extend:focus {
  color: #333333;
  text-decoration: none;
}
.btn-extend:active,
.btn-extend.active {
  outline: 0;
  background-image: none;
  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
.btn-extend.disabled,
.btn-extend[disabled],
fieldset[disabled] .btn-extend {
  cursor: not-allowed;
  pointer-events: none;
  opacity: 0.65;
  filter: alpha(opacity=65);
  -webkit-box-shadow: none;
  box-shadow: none;
}
.btn-extend {
  color: #333333;
  background-color: #ffffff;
  border-color: #cccccc;
}
.btn-extend:hover,
.btn-extend:focus,
.btn-extend:active,
.btn-extend.active,
.open > .dropdown-toggle.btn-extend {
  color: #333333;
  background-color: #e6e6e6;
  border-color: #adadad;
}
.btn-extend:active,
.btn-extend.active,
.open > .dropdown-toggle.btn-extend {
  background-image: none;
}
.btn-extend.disabled,
.btn-extend[disabled],
fieldset[disabled] .btn-extend,
.btn-extend.disabled:hover,
.btn-extend[disabled]:hover,
fieldset[disabled] .btn-extend:hover,
.btn-extend.disabled:focus,
.btn-extend[disabled]:focus,
fieldset[disabled] .btn-extend:focus,
.btn-extend.disabled:active,
.btn-extend[disabled]:active,
fieldset[disabled] .btn-extend:active,
.btn-extend.disabled.active,
.btn-extend[disabled].active,
fieldset[disabled] .btn-extend.active {
  background-color: #ffffff;
  border-color: #cccccc;
}
.btn-extend .badge {
  color: #ffffff;
  background-color: #333333;
}
.dl-horizontal dd:before,
.dl-horizontal dd:after,
.container:before,
.container:after,
.container-fluid:before,
.container-fluid:after,
.row:before,
.row:after,
.form-horizontal .form-group:before,
.form-horizontal .form-group:after {
  content: " ";
  display: table;
}
.dl-horizontal dd:after,
.container:after,
.container-fluid:after,
.row:after,
.form-horizontal .form-group:after {
  clear: both;
}
.btn-test {
  display: inline-block;
  margin-bottom: 0;
  font-weight: normal;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
  background-image: none;
  border: 1px solid transparent;
  white-space: nowrap;
  padding: 6px 12px;
  font-size: 14px;
  line-height: 1.42857143;
  border-radius: 4px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  color: #333333;
  background-color: #ffffff;
  border-color: #cccccc;
}
.btn-test:hover,
.btn-test:focus {
  color: #333333;
  text-decoration: none;
}
.btn-test:active,
.btn-test.active {
  outline: 0;
  background-image: none;
  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
.btn-test.disabled,
.btn-test[disabled],
fieldset[disabled] .btn-test {
  cursor: not-allowed;
  pointer-events: none;
  opacity: 0.65;
  filter: alpha(opacity=65);
  -webkit-box-shadow: none;
  box-shadow: none;
}
.btn-test:hover,
.btn-test:focus,
.btn-test:active,
.btn-test.active,
.open > .dropdown-toggle.btn-test {
  color: #333333;
  background-color: #e6e6e6;
  border-color: #adadad;
}
.btn-test:active,
.btn-test.active,
.open > .dropdown-toggle.btn-test {
  background-image: none;
}
.btn-test .badge {
  color: #ffffff;
  background-color: #333333;
}

何も指定しないで@importすると100kb超だったが、@import (reference)すると14Kbになった。

これでコードサイズがかなり削減されるな。。