使用環境
Name | Version |
---|---|
Dart Sass | 1.70.0 |
UIkit | 3.17.11 |
前書き
UIkit
をこよなく愛するFossa
です(笑)
UIkit
では、mixin
をhook
するために使っています。
例えば、下記の通りです。
.uk-alert { position: relative; margin-bottom: $alert-margin-vertical; padding: $alert-padding $alert-padding-right $alert-padding $alert-padding; background: $alert-background; color: $alert-color; @if(mixin-exists(hook-alert)) {@include hook-alert();} }
hook-alert
というmixin
が存在していれば、hook-alert
をinclude
します。
例えば、.uk-alert
にborder-radius
を追加したい場合は、下記の通りです。
@mixin hook-alert() { border-radius: 0.25rem; }
生成されたCSSは、下記の通りです。
.uk-alert { position: relative; margin-bottom: 20px; padding: 15px 29px 15px 15px; background: #f3f4f6; color: #4b5563; border-radius: 0.25rem; }
@use
や@forward
を使った場合、実現できるのか試してみました。
準備
scss
ディレクトリ配下に、下記のディレクトリとファイルを作ります。
種類 | 説明 | |
---|---|---|
File | main.scss | |
Directory | uikit |
オリジナル用 |
File | uikit/mixins.scss | |
Directory | uikit/components |
|
File | uikit/components/_index.scss | |
File | uikit/components/alert.scss | |
Directory | theme/mixins |
カスタムテーマ用 |
File | theme/mixins/alert.scss |
scss/main.scss
@use './uikit/components';
scss/uikit/mixins.scss
uikit/src/scss/mixins.scss
をコピーしてください。
scss/uikit/components/_index.scss
@forward './alert';
scss/uikit/components/alert.scss
中身は、uikit/src/scss/components/alert.scss
です。
一部だけ記載しますが、下記のように、記述します。
@use '../mixins' as original; @use '../../theme/mixins/alert' as custom; .uk-alert { position: relative; margin-bottom: $alert-margin-vertical; padding: $alert-padding $alert-padding-right $alert-padding $alert-padding; background: $alert-background; color: $alert-color; @if (mixin-exists("hook-alert", "custom")) { @include custom.hook-alert(); } @else if (mixin-exists("hook-alert", "original")) { @include original.hook-alert(); } }
上記は説明のため、それぞれ3行使ってます。
実際は下記の通り、1行ずつ記述しています。
@if (mixin-exists("hook-alert", "custom")) { @include custom.hook-alert(); } @else if (mixin-exists("hook-alert", "original")) { @include original.hook-alert(); }
scss/theme/mixins/alert.scss
@mixin hook-alert() { border-radius: 0.25rem; }
本題
カスタムテーマ用のディレクトリの位置は、定めた位置になるので、仕様にするしかないです。
カスタムテーマ用のmixin
が存在すれば、カスタムテーマ用のmixin
をinclude
します。
カスタムテーマ用のmixin
が存在しなくても、オリジナル用のmixin
が存在すれば・・・としなければ、内容が重複します。
@import
のように、Sass variables
は、オリジナルより先に読み込んで、mixin
は、オリジナルより後で読み込むというやり方は、出来ません。
結果
sass --no-source-map --quiet --style expanded scss/main.scss:public/css/style.css
.uk-alert { position: relative; margin-bottom: 20px; padding: 15px 29px 15px 15px; background: #f3f4f6; color: #4b5563; border-radius: 0.25rem; }
結論
UIkit
の場合は、Less
からSCSS
にコンバートしているので、そのロジックを書き直せば、実現可能だと思います。
実現可能だけど、「UIkit
は、Less
で使うのが無難かな?」と思いました。
もし、Sass
で@import
が使えなくなったら、「PostCSS
を使う方法もあるのかな?」と思います。*1
Variables
の件は、UIkit hook mixin 考察 (2) - 独学者Fossaに続きます。
後書き
日本語の記事では、私が知りたいことは、Googleで検索しても簡単には見つからず、ようやく言及している記事を見つけました。
追記(2024-02-04)
某CSS Frameworkのソースを覗いてみると、function
でSass variables
を使って、Sass variables
でfunction
を使っています。
@import
から、@use
や@forward
に置き換えると、loop
します。
上記で紹介した記事にも、loop
するトラブルに遭遇したことは書いてありますが、解決方法は書いてありません。
トラブルに遭遇したことを書いている日本語の記事自体、ほとんど見つかりません。
もちろん、暫定的に解決したのですが、レポジトリがarchived
されたので、更新されることはないでしょう。
もし更新される機会があったら、もっとスマートな解決方法を実装されたような気がして、気になります。
追記(2024-02-17)
Inverse
を使うのであれば、uikit/src/scss/mixins.scss
と同等のtheme/mixins.scss
を作成します。
@use '../../theme/mixins' as custom;
に変更すれば、Inverse
が使えるはずです。
Inverse
は、mixin
の中でmixin
をinclude
しているので、ちょっとややこしいですね。
*1:或いは、Stylus?