20200517のCSSに関する記事は12件です。

【RSpec】画面ごと CSSのテストができるGem「rspec-css」の使い方

この記事は

CSSの比較ができる rspec-css を作ったメモ

やりたかったこと

すぐ壊れるCSSのテスト

やり方

インストール方法

gem 'rspec-css'

CSSの記録

Capybara.default_driver = :selenium_chrome_headless
Capybara.app = Rack::File.new('spec/fixtures/files/')

visit 'sample.html'
files_path = 'spec/fixtures/files/sample.yml'
RSpec::CSS.print_silk(files_path, page) unless File.exist? files_path

比較

css_file = File.open files_path, 'r'
expect(page).to eq_screen_css(css_file.read)

結果

(compared using ==)

Diff:
@@ -17,7 +17,7 @@
  animation-timing-function: ease
  appearance: ''
  azimuth: ''
-  backface-visibility: hidden
+  backface-visibility: visible
  background: rgba(0, 0, 0, 0) none repeat scroll 0% 0% / auto padding-box border-box
  background-attachment: scroll
  background-blend-mode: normal

技術的ポイント

きっかけは「VCR便利だな」って軽い気持ちだったのが、RSpecは気軽に触れちゃいけないものだという畏怖の気持ちに変わり、Qiitaの記事とか参考になんとか出来たって感じなので、オープンソースは人々の協力によって支えられているのだ、という今の感謝の気持ちを心に留めてRailsを利用したい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【RSpec】Computed CSSの比較ができるGem「rspec-css」の使い方

この記事は

CSSの比較ができる rspec-css を作ったメモ

やりたかったこと

すぐ壊れるCSSのテスト

やり方

インストール方法

gem 'rspec-css'

CSSの記録

Capybara.default_driver = :selenium_chrome_headless
Capybara.app = Rack::File.new('spec/fixtures/files/')

visit 'sample.html'
files_path = 'spec/fixtures/files/sample.yml'
RSpec::CSS.print_silk(files_path, page) unless File.exist? files_path

比較

css_file = File.open files_path, 'r'
expect(page).to eq_screen_css(css_file.read)

結果

(compared using ==)

Diff:
@@ -17,7 +17,7 @@
  animation-timing-function: ease
  appearance: ''
  azimuth: ''
-  backface-visibility: hidden
+  backface-visibility: visible
  background: rgba(0, 0, 0, 0) none repeat scroll 0% 0% / auto padding-box border-box
  background-attachment: scroll
  background-blend-mode: normal

技術的ポイント

きっかけは「VCR便利だな」って軽い気持ちだったのが、RSpecは気軽に触れちゃいけないものだという畏怖の気持ちに変わり、Qiitaの記事とか参考になんとか出来たって感じなので、オープンソースは人々の協力によって支えられているのだ、という今の感謝の気持ちを心に留めてRailsを利用したい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

html要素のidにコロンを指定するのは注意!

そのidを検索する際の処理で躓く可能性があります、っていう話です。

はじめに

実績がない初心者なりに、アプリコンテストを目指したアプリの試作をしている今日此頃。

ところが、想定外していなかったミスで、数時間も食う事件が発生しました。

今回はその事件の原因について、自分への戒めも兼ねて記します。

事件背景

先述したアプリについて、ざっくりいうと、下のような構成です。

  • 外部API
  • フレームワーク
    • vuejs
  • レスポンシブデザイン向けライブラリ
    • bootstrap
  • 地図ライブラリ
    • leafletjs

要は外部APIからデータを取得し、そのデータと地図を連携させ、更にそれをbootstrapで良い感じに見せたい!というもの。

事件は、bootstrapのcollapse(折りたたみ)を使っている時に起こりました。

事件詳細

詳細なデータを受け取り、それをアコーディオン表示をさせようと、サンプルをほぼそのまま参考に、カード部分をコンポーネントにしました。vuejsが分かる人向けのイメージは以下。

Detail.vue
<template>
    <div id="detail">
        <div
        class="accordion"
        :id="cardParent"
        >
            <Card
            v-for="data in jsonData"
            :key="data['@id']"
            :cardId="data['@id']"
            :title="data['title']"
            :parentId="cardParent"
            />
        </div>
    </div>
</template>
Card.vue
<template>
    <div
    class="card"
    >
        <div
        class="card-header"
        :id="this.headerId"
        >
            <button
            class="btn btn-link btn-block text-left collapsed"
            type="button"
            data-toggle="collapse"
            :data-target="'#'+this.bodyId"
            aria-expanded="false"
            :aria-controls="this.bodyId"
            >
                {{this.title}}
            </button>
        </div>
        <div
        :id="this.bodyId"
        class="collapse card-body"
        :data-parent="'#'+this.parentId"
        >
            <p>テスト</p>
            <!--
                外部APIから取得したデータの
                詳細をここに記す
            -->
        </div>
    </div>
</template>
<script>

カードをどれだけ作るかは、外部APIのデータやユーザーの操作次第。なので、カードやその内部要素のidは、コンポーネント内では決められません。

そこで、外部APIのデータのidを元に、カードや内部要素のidを決めることに。

idがid00001なら、カードはid00001、内部要素はid00001_headerとするように、コードを記述しました。

(vuejsが分かる人向けに言うと、Card.vueではcardIdをプロパティに受け取り、それに基づき、算出プロパティで内部要素用idをセットしています)

サンプルほぼそのままなので、これで問題はないはず!と動かした所、最初は問題なく表示されているように見えました。

でも、何かがおかしい。よく見ると、アコーディオン表示が開けない。

しかし、サンプルコードを見比べても、動作しているhtmlを見ても、何も問題がない。

加えて、display : noneできちんとDOMは描画されている。

一体、何だ!?何が原因なんだ!?!?!?


犯人

結局、上記のミスに気づくのに数時間を費やしてしまいました。

まだ扱いに慣れていないbootstrapばかりに気を取られて、原因は全く関係のない所にあったことに気づくのが遅かった為です。

実は、外部APIのデータのidをもとに、カードのidとしたのが、犯人でした。

外部APIからのjsonデータ(のid)に、記号、コロンなどが含まれていました。

このidを、直接カードのidに指定していたのが、全ての問題の始まり。

別に、htmlの要素のidに、コロンを含む記号は、問題なく指定できます。

シンプルなgetElementById("変なid名")も、特に問題なく動きます。

しかし。ライブラリによっては、id名を元にする検索などで、思うように動いてくれない場合があります

今回は恐らく、bootstrapが依存するjQueryの問題ではないかと個人的に考えています。

(参考 : https://www.buildinsider.net/web/jqueryref/036 )

終わりに

教訓はこの2つ。以後気をつけたい。

  • idに記号を使う場合は要注意
    • ハイフンなど以外、入れないのが非常に好ましい
  • 外部データの値をidに使う場合は要注意
    • 意図せず記号が入ってしまう場合がある

余談

該当のコードは、v-forの要素数オプションも使って、下のようにid名を工夫した。

Detail.vue
<template>
    <div id="detail">
        <div
        class="accordion"
        :id="cardParent"
        >
            <Card
            v-for="(data,i) in jsonData"
            :key="data['@id']"
            :cardId="'card'+i"
            :title="data['title']"
            :parentId="cardParent"
            />
        </div>
    </div>
</template>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Day15 #HTML/CSS汎用的小技

headerの固定・横一杯・常に上側に表示

.header {
  position: fixed;
  width: 100%;
  z-index: 1;
}

-positionプロパティ

|static |初期値。特に配置方法を指定しない。 |
|relative |相対位置への配置となる。|
|absolute |絶対位置への配置になる。absoluteを指定した親ボックスにstatic以外の値が指定されている場合に、その親ボックスの左上が基準位置になる。親ボックスに指定がない場合は、body要素が起点となる。|
|fixed |absoluteと同じく絶対位置への配置になるが、画面をスクロールした際も位置が固定されたままになる。|
|sticky position |relativeのように位置が指定され、fixedのように固定される。|

-z-index
z軸方向(画面の手前・奥)の数値を指定するイメージ

親要素内で子要素をど真ん中に置きたい時

image.png

htmlの親子関係
 <div class="side-header">     # ①
  <div class="side-box"></div> # ②
 </div>
css子要素をど真ん中に
.side-header{
  display: flex;       #中に入ってる要素を横並びに
  align-items: center;  #中に入ってる要素を中央配置
}

.side-box{
  height: 20px;
  width: 260px;
  background-color: #ffffff;
  margin: 0 20px;  #左右のmarginで中央配置
}
  • margin: 0 auto;

  • borderの設定

border色・太さ・種類→順不同
.Edit-btn{
  border: #eeeeee 1px solid;  #この色で、color(font)も自動適用
  font-size: 16px;
  padding: 15px 20px;
}
  • 投稿フォームの設定
formタグとinput
<div class="form">
 <form>
  <input class="input-text" type="text" placeholder="type a text">
  <input class="send-btn" type="submit" name="commit" value="send">
 </form>
</div>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

先日いよいよAnimate.cssがv4になったのでwow.jsの使い方にコツがいる

Animate.cssとWOW.js、駆け出しwebエンジニアなら誰しもが一度は通る道ですよね。
とくにWOW.jsのはっちゃけたオフィシャルサイトは印象強いかも。

WOW.js
本家: https://github.com/graingert/wow
Fork: https://wowjs.uk/
Forkの方がStar多い...。内容はほぼ同じです。

そんな彼らですが、先日のAnimate.css v4.0.0リリースで、使い方にコツがいるようになりました。

変更点

  • クラス名にprefixがつくようになった
    • Animate.cssから提供される全てのクラス名にanimate__というprefixがつきます。
  • utilityクラス名の命名が変更になった?(DurationとかDelayとか)

① Animate.cssを導入

npmの場合

npm install animate.css --saveとかyarn add animate.cssとかする

node_modules下のcssファイルは ~ を使って読み込むのですよ。こんな感じ▼

@import "~animate.css/animate.min.css";

CDNの場合

公式サイトに沿ってCDN経由で読み込む。

② WOW.jsを導入

GitHubからローカルに導入するか、npm install wowjsでいけます。探すとCDNもあります。(公式からの案内はない)。

本家 ... wowjs
Fork ... wow.js

③スクリプトを配置

Typescriptの例ですがJavascriptでも同じです。
TSの場合はdefinition fileは提供されていないので require 関数で読み込みます。
ESLintを導入しているひとは例外を認めるコメントを書く必要があるかもです。下を参考にどうぞ。

app.ts
// eslint-disable-next-line @typescript-eslint/no-var-requires
const WOW = require('wow.js');

new WOW({
  animateClass: 'animate__animated'
}).init();

これだけで従来通り使えます。

ただしアニメーションのクラス名も
fadeIn -> animate__fadeIn
と変わっているのでお気をつけくださいまし。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

最低限知っておきたいBootstrapの使い方

はじめに

ここでは、Bootstrapの基本的な利用方法について解説します。

スターターテンプレート

Bootstrapには、色々なデザインが用意されていますが、その大元となる「スターターテンプレート」があります。

よく使うデザイン

Jumbotron

ウェブページのヘッダーのテンプレートとして使いやすいデザインです。
https://getbootstrap.jp/docs/4.4/components/jumbotron/

Alerts

処理完了やエラーメッセージの表示に使えます。
alert-のclass属性は、色の指定にも使えるので便利です。

https://getbootstrap.jp/docs/4.4/components/alerts/

Buttons

他のページへのリンクやフォームの送信ボタンなどに使えます。
こちらもbtn-successなどのクラス属性は、色を変える時に使えます。

https://getbootstrap.jp/docs/4.4/components/buttons/

Cards

ブログの記事一覧で個々の記事を表示したりするのに使えます。

https://getbootstrap.jp/docs/4.4/components/card/

Forms

新規登録や記事投稿などのフォームに使えます。

https://getbootstrap.jp/docs/4.4/components/forms/

Navbar

ヘッダー部分のメニューバーなどとして使えます。

https://getbootstrap.jp/docs/4.4/components/navbar/

Pagination

記事一覧ページなどのページネーションに使えます。

https://getbootstrap.jp/docs/4.4/components/pagination/

チートシート

Bootstrapのチートシートのページには、様々なデザインと、対応するコードがまとめられています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

encoding

Hellow world

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Font Awesomeについて

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「こどもれっどまいん」というテーマを作っています。

20200517: 追記

  • フォントの扱いに関して不備・対応が必要な点がありましたので、いちど公開を内容を見直しとさせていただきます。(記事はこちらの問題点を改めるため、このままとしておきます)
    • コメントでご指摘くださった方、ありがとうございます!
    • リポジトリ側はテーマに関しての利用方法、READMEを修正しておりますが、引き続き不備は修正して参ります
  • 利用フォントについてスクリーンショットに情報を添えております
  • GitHub Actionsについて少し追記しています

20200518: 追記

  • リポジトリ側は、テーマに組み込んだlatin文字用のフォントは、手書きスタイルのPatrick Hand(Google font)の利用、日本語はKosugi Maru(Google font)をベースに変更いたしました
  • スクリーンショットで提示しているあんずもじは配置手順を記載する形に変更しました

はじめに / これはなに?

こどもれっどまいん」という名前で、Redmineの見た目をカスタマイズするテーマを作っています。

昨年から学習を兼ねてちょこちょこ作っていたのですが、5/4の「みどりの日」、5/5の「こどもの日」にかけて、緑ベースのものを作ったので、紹介してみようと思います。

どんなもの?

いわゆるテーマなので、Redmine本体に機能を追加するものではありません。
CSSを使って見た目をカスタマイズするものになります。

以下、一部を掲載します。

※20200517: スクリーンショットの画像では、日本語フォントに「あんずもじ」を適用しております。フォントを組み込まない場合は、日本語は「Noto Serif JP」(Google font) を利用させていただいております。

ログイン画面 (アルファベット: Patrick Hand用時)

add-info.png

フォーラム画面 (あんず文字利用時)

forum-sample.png

フォーラム画面 (Kosugi Maru利用時)

forum-sumple-with-Noto-Serif-JP.png

チケット表示 (PC: あんず文字利用時)

チケット表示.jpg

チケット表示 (レスポンシブ: Kosugi Maru利用時)

チケット表示-Noto-Serif-JP.png

ドラスティックにUIの位置まで変えたりはせず、手書きフォントを適用したり、フォームのスタイルを変える形で調整しています。

なぜつくったの?

JIRA Jr. や various WordPress themes for kids and children を参考に、「小中学生向け、もしくはやわらかい感じのテーマがあったらいいな」....と思って作成してみました。
(わたし自身は素のRedmineが嫌いではありません)

実用に耐えるかはまだ怪しいのですが、子どもたちや学生が複数で利用する場合、チケットトラッキングよりも、フォーラムやWiki、ニュースといった情報共有のための機能が役に立つかな、と個人的に思っています。

このため、フォーラムやWiki、ニュースまわりも少し調整しています。

どうやってためせるの?

Redmine環境をお持ちの場合

  • 既存のRedmineのディレクトリ/public/themes/ 以下に展開します
  • 配置後にRedmineを再起動します

環境がない場合

  • Dockerを稼働できる環境があれば、お手元でRedmine込みで試すことが可能です
  • developmentモードで稼働なので、「評価用」としての起動になります
  • 以下はDockerHubに登録してあるイメージをpullして起動する例です
docker pull akiko/redmine_theme_kodomo_midori

# run redmine localy and enabled to access via port 3000
docker run --rm --name kodomo_redmine -p 3000:3000 -it akiko/redmine_theme_kodomo_midori:latest

開発の仕方

基本はRedmineをdevelopmentモードで手元で起動しつつ、テーマ専用のディレクトリにCSSやJavaScriptを配置し、こつこつ編集と表示を確認していくスタイルです。

実のところ、フロントエンドの知識は学習中で、CSSもJSもモダンな書き方はしていません。ソースコードは.css, .jsをそのまま書いており、トランスパイルやminifyといったことはしていません。

テーマでできること

プラグインとは異なり、見た目のカスタマイズが基本になります。
ただし、theme.js という名前でCSSと合わせてJavaScriptを1つ読み込むことができます。

こちらを利用し、コンテンツがロードされたらHTMLの要素を差し込むといったことが可能です。

現時点で試しているJavaScriptでの調整は、以下の通りです。

  • ログイン / ログアウト時にローディング画面を表示する
  • クローズされたチケットを表示する場合、画面下に「Great Job!」のリボンを表示する
  • フッタにテーマの説明を添える

残念ながらJavaScriptを差し込むヘッダはRedmine側に依存しますので、module形式で複数のJSを読み込んだりはできませんが、それでもいろいろと工夫はできそうです。

難しいなと思うこと

プラグインの場合は、メッセージファイル(多言語化)をしやすいのですが、JavaScriptで文言をさしこむような場合は、ユーザの言語の判定や言語にあったメッセージの取得をどうしたものか、と悩みました。

ですので、あまり柔軟にメッセージを画面に追加することはできないかもと思っています。(i18nのファイルを用意したとして、サーバサイド側とは別管理になってしまうかな?)

この作業での学び

  • フロントエンドのビルド環境についてはこれからだけど、JSでの拡張ができることがわかった
  • 簡単に試せるようにGitHub ActionsとDockerHubでの連携をやってみた

というあたりです。

GitHub Actionsの設定: 20200518追記

GitHubのmasterブランチへのマージ -> GitHubのリソース上でのDocker imageのビルド -> DockerHubへのpushを行っています。
とは言っても、こまかく1から設定を書いたわけではなく、GitHub Actionsとして公開されている以下の設定を組み込んだだけになります。

※実質は、DockerHubへpushするためのシークレットの設定、DockerHub側のリポジトリに書き換え、どのアクションでbuildを発動させるかといった調整のみで住んでいます。
こちらについては、また別途触れたいと思います。

できたらいいなと思うこと

小中学生向け、という趣旨で作ってみましたが、Redmineの全ての機能をカバーしているわけではなく、まだまだ見た目的にもスタイルが整っていないところがたくさんあります。(ソースコードもモダンではないし綺麗でもないので...)

ただ、もしも実用に耐えそう、もしくは耐えるものにしてみたいと言う方は、ぜひ、足りない部分や改善点をissueやプルリクエストで上げていただけたら嬉しいです。

テーマだけではカバーし切れていない部分は、簡単なJavaScriptでの調整や、プラグインと連携しての開発なども視野に入れていますので、ご意見のほどよろしくお願いいたします。

もちろん、「自分でテーマを作ってみたい!」という方に、なにか参考になりましたら幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者によるプログラミング学習ログ 318日目

100日チャレンジの318日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
318日目は、

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CSSの子孫セレクタを使うなら子セレクタの方が良いかもしれない理由

はじめに

設計なので、これが正解!というものはないです。
時と場合によります。
今回のケースは、パーツを作っていて、スタイルを当てたい時だと考えています。


子孫セレクタとは ・・・ .class .class のことで、子や孫以降全て
子セレクタ ・・・ .class > .class のことで、直接子要素のみ


結論

  • 影響範囲を小さく出来るから
  • 影響しているスタイルを打ち消さなくても良くなるから

設計で重要なことは予測しやすいこと

CSSの設計で重要なことに予測しやすいというものがあります。
それは他のスタイルが影響せずに、自分が書いたとおりに動くとされていることです。

解説

HTML用意します

<div class="sidebar">
  <h1 class="text">サイドバー</h1>
  <ul class="lists">
    <li class="list"><a class="text">リスト1</a></li>
    <li class="list"><a class="text">リスト2</a></li>
    <li class="list"><a class="text">リスト3</a></li>
  </ul>
</div>

サイドバーという文字を大きくしたいな〜って思った時に、

子孫セレクタで書くと、

.sidebar .text {
  font-size: 40px;
}

予期していないところまで文字が大きくなってしまいます。

image.png

子セレクタで書くと

.sidebar > .text {
  font-size: 40px;
}

image.png

良い感じ?

個人的には、全てclass命名して書いていきたい

理由は
- .class > .class.class より詳細度が高くなり、スタイルが効かないことがある
- HTML側がdivなどでwrapされるという変更が起きた時に、スタイルも編集しなくてはならない(HTMLに依存し、変更に弱い)

  1. 子孫セレクタ使うんだったら、影響範囲が小さい子セレクタを使いたい
  2. 子セレクタ使うと、上記で述べた理由がある

ので、class付与してやりたいですね...

じゃあ、CSSの名前被るんだけど!?って話になるんですが、BEMなどの名前空間っぽいやつがあります。そもそもBEMだったら、名前が被る事なんて少ないですね。もっと言うなら、Shadow DOMやCSS in JS、CSSmodulesとかあるんですが、その話になるとずれていきます。もし、コンポーネント単位で作っていても、その中でスタイルの競合等があれば、困りますよね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

sassでmargin, paddingのhelperクラスを作る

margin, paddingのhelperクラスはBootstrapにはあるけどBulmaにはない。
あとBootstrapのも個人的には微妙に使い勝手が悪い。
ということで今までにもいろんなプロジェクトでいろんな書き方してきたけど今後も使い回せるように残しておきます。

コード

$max: 3
$frac-max: 1
$default-unit: 'rem'
$props: (m: margin, p: padding)
$directions: (t: top, b: bottom, l: left, r: right)

@for $i from 0 through $max
  $unit: if($i == 0, '', $default-unit)

  @each $p-short, $p-full in $props
    .#{$p-short}-#{$i}
      #{$p-full}: #{$i}#{$unit}!important

    @each $d-short, $d-full in $directions
      .#{$p-short}#{$d-short}-#{$i}
        #{$p-full}-#{$d-full}: #{$i}#{$unit}!important

// 0.25単位
@for $i from 0 through $frac-max
  @for $n from 1 through 3
    $num: 0.25 * $n
    $label: if($num == 0.5, '5', $num * 100)

    @each $p-short, $p-full in $props
      .#{$p-short}-#{$i}_#{$label}
        #{$p-full}: #{$i + $num}#{$default-unit}!important

      @each $d-short, $d-full in $directions
        .#{$p-short}#{$d-short}-#{$i}_#{$label}
          #{$p-full}-#{$d-full}: #{$i + $num}#{$default-unit}!important

使い方

普段paddingmarginemremで指定するのでその仕様で作っています。
細かく使い分けられるように0.25単位のクラスも作りました。
そこまで細かくなくていい場合はコメント以下を削除してください。
ループを組み込んでしまえばもっと共通化して短くできるけど、切り離したいこともありそうなので分けました。

今回は出力されるcssも掲載するため$maxを3にしていますが、プロジェクトでは10くらいまで作ります。
ゆったりとしたレイアウトで広めのスペースが必要になることが結構あるためです。
一方0.25単位クラスの上限$frac_max12で十分かなと思います。
margin-bottom: 5.75remとか指定することはほぼないと思いますし・・・

アウトプット

以下のようになります。
Sasserじゃない方は以下だけコピペして使ってください。

.m-0 {
  margin: 0 !important;
}

.mt-0 {
  margin-top: 0 !important;
}

.mb-0 {
  margin-bottom: 0 !important;
}

.ml-0 {
  margin-left: 0 !important;
}

.mr-0 {
  margin-right: 0 !important;
}

.p-0 {
  padding: 0 !important;
}

.pt-0 {
  padding-top: 0 !important;
}

.pb-0 {
  padding-bottom: 0 !important;
}

.pl-0 {
  padding-left: 0 !important;
}

.pr-0 {
  padding-right: 0 !important;
}

.m-1 {
  margin: 1rem !important;
}

.mt-1 {
  margin-top: 1rem !important;
}

.mb-1 {
  margin-bottom: 1rem !important;
}

.ml-1 {
  margin-left: 1rem !important;
}

.mr-1 {
  margin-right: 1rem !important;
}

.p-1 {
  padding: 1rem !important;
}

.pt-1 {
  padding-top: 1rem !important;
}

.pb-1 {
  padding-bottom: 1rem !important;
}

.pl-1 {
  padding-left: 1rem !important;
}

.pr-1 {
  padding-right: 1rem !important;
}

.m-2 {
  margin: 2rem !important;
}

.mt-2 {
  margin-top: 2rem !important;
}

.mb-2 {
  margin-bottom: 2rem !important;
}

.ml-2 {
  margin-left: 2rem !important;
}

.mr-2 {
  margin-right: 2rem !important;
}

.p-2 {
  padding: 2rem !important;
}

.pt-2 {
  padding-top: 2rem !important;
}

.pb-2 {
  padding-bottom: 2rem !important;
}

.pl-2 {
  padding-left: 2rem !important;
}

.pr-2 {
  padding-right: 2rem !important;
}

.m-3 {
  margin: 3rem !important;
}

.mt-3 {
  margin-top: 3rem !important;
}

.mb-3 {
  margin-bottom: 3rem !important;
}

.ml-3 {
  margin-left: 3rem !important;
}

.mr-3 {
  margin-right: 3rem !important;
}

.p-3 {
  padding: 3rem !important;
}

.pt-3 {
  padding-top: 3rem !important;
}

.pb-3 {
  padding-bottom: 3rem !important;
}

.pl-3 {
  padding-left: 3rem !important;
}

.pr-3 {
  padding-right: 3rem !important;
}

.m-0_25 {
  margin: 0.25rem !important;
}

.mt-0_25 {
  margin-top: 0.25rem !important;
}

.mb-0_25 {
  margin-bottom: 0.25rem !important;
}

.ml-0_25 {
  margin-left: 0.25rem !important;
}

.mr-0_25 {
  margin-right: 0.25rem !important;
}

.p-0_25 {
  padding: 0.25rem !important;
}

.pt-0_25 {
  padding-top: 0.25rem !important;
}

.pb-0_25 {
  padding-bottom: 0.25rem !important;
}

.pl-0_25 {
  padding-left: 0.25rem !important;
}

.pr-0_25 {
  padding-right: 0.25rem !important;
}

.m-0_5 {
  margin: 0.5rem !important;
}

.mt-0_5 {
  margin-top: 0.5rem !important;
}

.mb-0_5 {
  margin-bottom: 0.5rem !important;
}

.ml-0_5 {
  margin-left: 0.5rem !important;
}

.mr-0_5 {
  margin-right: 0.5rem !important;
}

.p-0_5 {
  padding: 0.5rem !important;
}

.pt-0_5 {
  padding-top: 0.5rem !important;
}

.pb-0_5 {
  padding-bottom: 0.5rem !important;
}

.pl-0_5 {
  padding-left: 0.5rem !important;
}

.pr-0_5 {
  padding-right: 0.5rem !important;
}

.m-0_75 {
  margin: 0.75rem !important;
}

.mt-0_75 {
  margin-top: 0.75rem !important;
}

.mb-0_75 {
  margin-bottom: 0.75rem !important;
}

.ml-0_75 {
  margin-left: 0.75rem !important;
}

.mr-0_75 {
  margin-right: 0.75rem !important;
}

.p-0_75 {
  padding: 0.75rem !important;
}

.pt-0_75 {
  padding-top: 0.75rem !important;
}

.pb-0_75 {
  padding-bottom: 0.75rem !important;
}

.pl-0_75 {
  padding-left: 0.75rem !important;
}

.pr-0_75 {
  padding-right: 0.75rem !important;
}

.m-1_25 {
  margin: 1.25rem !important;
}

.mt-1_25 {
  margin-top: 1.25rem !important;
}

.mb-1_25 {
  margin-bottom: 1.25rem !important;
}

.ml-1_25 {
  margin-left: 1.25rem !important;
}

.mr-1_25 {
  margin-right: 1.25rem !important;
}

.p-1_25 {
  padding: 1.25rem !important;
}

.pt-1_25 {
  padding-top: 1.25rem !important;
}

.pb-1_25 {
  padding-bottom: 1.25rem !important;
}

.pl-1_25 {
  padding-left: 1.25rem !important;
}

.pr-1_25 {
  padding-right: 1.25rem !important;
}

.m-1_50 {
  margin: 1.5rem !important;
}

.mt-1_50 {
  margin-top: 1.5rem !important;
}

.mb-1_50 {
  margin-bottom: 1.5rem !important;
}

.ml-1_50 {
  margin-left: 1.5rem !important;
}

.mr-1_50 {
  margin-right: 1.5rem !important;
}

.p-1_50 {
  padding: 1.5rem !important;
}

.pt-1_50 {
  padding-top: 1.5rem !important;
}

.pb-1_50 {
  padding-bottom: 1.5rem !important;
}

.pl-1_50 {
  padding-left: 1.5rem !important;
}

.pr-1_50 {
  padding-right: 1.5rem !important;
}

.m-1_75 {
  margin: 1.75rem !important;
}

.mt-1_75 {
  margin-top: 1.75rem !important;
}

.mb-1_75 {
  margin-bottom: 1.75rem !important;
}

.ml-1_75 {
  margin-left: 1.75rem !important;
}

.mr-1_75 {
  margin-right: 1.75rem !important;
}

.p-1_75 {
  padding: 1.75rem !important;
}

.pt-1_75 {
  padding-top: 1.75rem !important;
}

.pb-1_75 {
  padding-bottom: 1.75rem !important;
}

.pl-1_75 {
  padding-left: 1.75rem !important;
}

.pr-1_75 {
  padding-right: 1.75rem !important;
}

おしまい

変数のスコープに結構つまづきました。
あとif関数というのを初めて知りました。
使いやすい!
しかしSassの公式ドキュメントってなんか見にくい・・・?

参考

Sass if文 ( @ifディレクティブ ) の中で変数を使う時の罠 - かもメモ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む