コンテンツにスキップ

SCSSをCSSに置き換える

このセクションではSCSSのmixinなどを現代的なCSSに置き換えるためのtipsなどを提供します。

余白のユーティリティクラス

SCSSコード

utility.scss
$spaceamounts: (0, 5, 10);
$sides: (top, bottom, left, right);
@each $space in $spaceamounts {
@each $side in $sides {
.u-m#{str-slice($side, 0, 1)}-#{$space} {
margin-#{$side}: #{$space}px !important;
}
.u-p#{str-slice($side, 0, 1)}-#{$space} {
padding-#{$side}: #{$space}px !important;
}
}
}
/*
生成されるCSS:
.u-mt-0 { margin-top: 0px !important; }
.u-mb-0 { margin-bottom: 0px !important; }
...
.u-mt-0, .u-mb-0, .u-ml-0, .u-mr-0, .u-pt-0, .u-pb-0, .u-pl-0, .u-pr-0 { ... }
.u-mt-5, .u-mb-5, .u-ml-5, .u-mr-5, .u-pt-5, .u-pb-5, .u-pl-5, .u-pr-5 { ... }
.u-mt-10, .u-mb-10, .u-ml-10, .u-mr-10, .u-pt-10, .u-pb-10, .u-pl-10, .u-pr-10 { ... }
*/

CSSへの置き換え(余白のユーティリティクラス)

tokens.css
:root {
--system-space-small: 1.25rem /* 20px */;
--system-space-medium: 2.5rem /* 40px */;
--system-space-large: 6rem /* 96px */;
--contents-spacing: var(--system-space-small);
}

解説

ユーティリティクラスは基本的に不要です。特に縦余白については制作時にデザインルールを変数化します。 そのうえで、どうしても余白を調整しなければならないページではローカル変数として、グローバル変数を更新します。

ToDo:ユーティリティクラスを使わないことについて、コンテンツができたらリンクする。

単位の変換

SCSSのコード(余白のユーティリティクラス)

_function.scss
@function vw($width, $base-width: 1440) {
@return calc($width / $base-width * 100vw);
}
@function percent($width, $base-width: 1440) {
@return calc($width / $base-width * 100%);
}
@function imgRatio($width, $height) {
@return calc($height / $width * 100%);
}
@function rem($pixel-size) {
@return calc($pixel-size / 16 * 1rem);
}

この書き方には一定のメリットがあります。SCSSではコンパイル時に計算結果を返すことが出来ます。 ブラウザでcalcの計算をすることは確実にコンピューティングリソースを消費します。
ただし、現実的にはその影響は極わずかであり、今後もマシンスペック、ブラウザの向上が続く限りCSSの計算リソースがレンダリングのボトルネックになることは起こらないでしょう。

CSSへの置き換え(単位の変換)

vwなど相対的な幅、高さ

rootでグローバル変数を準備しコンテンツ内のCSSでcalcを使用します。

tokens.css
:root {
/* ... some tokens */
--viewport-width: 1440; /* PCデザイン幅 */
@media (width > 768px) {
--viewport-width: 375; /* スマートフォンデザイン幅 */
}
}
base.css
:root {
/* 変換するための比率をbase.cssで規定 */
--viewport-ratio: calc(1 / var(--viewport-width) * 100dvi);
}
contents.css
.liquid-view {
--box-size: 700;
width: calc(var(--box-size) * var(--viewport-ratio));
@media (width < 768px) {
--box-size: 200;
/* またはスマートフォン幅では画面幅いっぱいにしたい場合↓ */
/* --box-size: var(--viewport-width); */
}
}

文字サイズ pxrem

そのままremで書きましょう。 また文字サイズ、余白についてはグローバルの変数で定義したもののみ使用するようにプロジェクト内で共有しましょう。

計算してfont-sizeを指定したい場合は次のようなアイディアがあります。

:root {
--rem: 1rem / 16;
}
/* 18pxにしたい */
.text-large {
font-size: calc(18 * var(--rem));
}

画像の画角

SCSSのコード(画像の画角)

@function imgRatio($width, $height) {
@return calc($height / $width * 100%);
}

img要素はHTML側でwidthheightを設定しているため多くの画像で画角の再調整は不要です。 必要な場合はaspect-ratioを使用してください。

img {
width: 100%;
height: auto;
}

上記のコードではHTMLで設定されているwidthheightaspect-ratioとして機能します。

@mixinのアイディア

SCSSのコード(@mixinのアイディア)

link.scss
@mixin link($base-color: black, $hover-color: teal) {
color: $base-color;
text-decoration-line: underline;
text-decoration-thickness: 3px;
&:hover {
color: $hover-color;
}
}
.link {
@include link();
}
.link.link--my-fancy-link {
@include link($base-color: hotpink, $hover-color: mediumvioletred);
}
.link.link--another-lovely-link {
@include link($base-color: turquoise, $hover-color: cadetblue);
}

CSSへの置き換え(@mixinアイディア)

_import/components/link.css
[class^=ui-link],[data-ui="link"] {
color: var(--ui-link-text-color);
text-decoration: underline;
text-decoration-thickness: 3px
@media(any-hover: hover) {
&:hover {
color: var(--ui-link-text-color-hover);
}
}
}
.ui-link--my-fancy-link,.my-fancylink[data-ui="link"] {
--ui-link-text-color: hotpink;
--ui-link-text-color-hover: mediumvioletred;
}
.ui-link--another-lovely-link,.another-lovely-link[data-ui="link"] {
--ui-link-text-color: turquoise;
--ui-link-text-color-hover: cadetblue;
}

この例では最終的な出力サイズと拡張性はCSSが有利です。

メディアクエリ

SCSSのコード

@use "sass:map";
@mixin mq($size: "md") {
@media #{map.get($breakpoints, $size)} {
@content;
}
}
@mixin mq-min($min-width) {
@media all and (min-width: #{$min-width}px) {
@content;
}
}
@mixin mq-max($max-width) {
@media all and (max-width: #{$max-width}px) {
@content;
}
}
@mixin mq-min-max($min-width, $max-width) {
@media all and (min-width: #{$min-width}px) and (max-width: #{$max-width}px) {
@content;
}
}

CSSではメディアクエリ内の値に対して変数を使用できません。メディアクエリに関していえば現時点ではSCSSの方が優れていることは間違いありません。
一つの手立てはメディアクエリの使用を少なくするです。たとえばPCとスマートフォンで文字サイズが切り替わる場合、以下のように:rootでまとめて設定します。

:root {
--system-text-size-default: 1rem /* 16px */;
/* ... other text scale ... */
@media (width > 768px) {
--system-text-size-default: 1.125rem /* 18px */;
/* ... other text scale ... */
}
}