【コーディング効率化】Web制作者のVScodeスニペットのススメ

お久しぶりです。
皆さんはエディタのVSCodeのスニペットを使ってますか？

自分ははWeb制作のお仕事を始めてもうすぐ半年になりますが、早く一人前になるために色々試行錯誤をしております。
その中でもVSCodeのスニペットをコツコツ登録してきたことが、現在のコーディングの時短になっていると思っています。

ですが、自分のまわりでスニペットを使っている人が少ないため、もっとスニペット使いと交流したいと思い、この記事を執筆しました。

ぜひ最後まで見ていただけると嬉しいです。

## 1_最初に

### 1_1 snipetとは
スニペット（snippet）というのは、良い短いテンプレートのようなものです。定型文とも言います。
主な使い方として、メールやチャットの定型文やコードのよく使うパターンを登録し、簡単に入力できるようにしたものです。
これによって、ループや条件文などの繰り返しコードパターンが、ごく少ないコマンドやキー入力で済むため、開発効率が非常に高まります。

### 1_2 VSCodeのスニペット

clippyやAlfredのようなアプリにもスニペット機能がついていますが、自分は無料で使用できるVisual Studio Cod(VSCode)に搭載されているスニペットを推します。

VSCodeに搭載されているスニペットはかなり優秀で、入力後のカーソルの位置を指定できたり、選択肢を表示できたりと、クリエイティブな使い方をすることができます。
また、プログラミング言語ごと（ファイルの拡張子ごと）に別々のスニペットを設定できるため、非常にコーディングに特化した機能と言えます。

## 2_基本的な作り方

### 2_1 スニペットの作り方
スニペットはあらかじめ決められているものだけではなく、自作することが可能です。
設定できるスニペットの数には、一応限りがないことになっています。

以下は Macでの登録方法です。
1. 左上の「Code」→「基本設定」→「ユーザースニペット」と選択
2. テキストボックスにスニペットを使用する拡張子の言語を入力 (HTML, Mark downなど)

言語の選択新しい設定用ファイルが開く「言語名.json」(HTMLならば html.json)ので、新しく登録したいスニペットを追加していきます。

### 2_2 スニペットの書式
ユーザースニペットの設定ファイルの書式について解説します。
スニペットの設定を記述するファイルはJSON形式です。

Snippets は、prefix（合言葉のようなもの）が入力されそうになったときにサジェストに出現し、
それを選択すると、定義しておいた Snippets が展開されます。
スニペットの書式は下記のような形です。

```
"スニペットの名前": {
    "prefix": ["スニペットを呼び出すトリガー"],
    "body": [
        "呼び出されるスニペットの内容"
        ],
    "description": "スニペットの説明文"
    }
```


基本的に新しく追加する場合はを以下設定すれば使えます。(descriptionは任意です。)

- **スニペットの名前**
  - 関数名のようなものです。
- **prefix (スニペットを入力するときのトリガーになる文字列)**
  - ここに設定された文字列入力を開始するとスニペットの候補を表示します。
- **body (呼び出されるスニペットの内容)**
  - スニペット選択時に挿入される定型文を記載します。
  - タブストップなどを設定すると、カーソルの位置をコントロールできます。
- **description (スニペットの説明文)**
  - サジェストに説明文として表示される部分です。
  - 登録は任意ですが、スニペット数が増えてくると探しやすくて便利です。

### 2_3 特殊文字を文字列として出力させる
注意点として、本文の中で「”(ダブルクオーテーション)」や「$(ダラー)」などの文字列は使えません。
スニペットとしてダブルクォーテーションを出力したい場合は、バックスラッシュ（￥）でエスケープします。
バックスラッシュ自身を出力する場合も、バックスラッシュでエスケープします。

以下はダブルクオーテーションを巣にペットに組み込む時の例です。

```
    "calss=\"class\""
```

### 2_3 書き方の例
以下のようなスニペットを登録してみます。

- スニペット名：HelloWorld
- スニペットの説明：HelloWorldを出力する
- トリガー(今回2パターン)：「hello」、「h-w」のどちらかでサジェスト
- 挿入される定型文は以下のコード

```
<p class="test">
    hello world
</p>
```

完成系はこちらです。

```
"HelloWorld": {
	"prefix": ["hello","h-w"],
	"body": [
		"<p class=\"test\">",
		"    hello world",
		"</p>"
	],
	"description": "HelloWorldを出力する"
}
```

### 2_5 簡単なsnipetの登録のツール
スニペットを手軽に登録する方法として、[snippet generator](https://snippet-generator.app/?description=&tabtrigger=&snippet=&mode=vscode) があります。
この後紹介する組み込み変数は自分で書く必要がありますが、こちらは改行や特殊文字もちゃんと置換してくれるため、非常に便利です。
自分は１年以上手打ちや「スニペットを登録するスニペット」を活用していましたので早く知りたかったです・・orz

- [snippet generator](https://snippet-generator.app/?description=&tabtrigger=&snippet=&mode=vscode)

## 3_タブストップ

### 3_1 タブストップの設定
タブストップを使用すると、エディターカーソルをスニペット内で移動させることができます.
スニペット内で「$n」と記述すると、タブストップの設定ができます。(**※「＄」と数字の入力は半角英数字です。**)
- 「＄1」、「＄2」を使用してカーソル位置を指定します。
- 「＄0」と指定するとカーソルの最終位置を示します。
- Tabキーを押すと数字の順番にカーソルの位置が移動します。
- 同一のタブストップを複数設定すると、カーソルが同期し同時編集できるようになります。

### タブストップの既定値を設定する
タブストップに既定値(プレースホルダーテキスト)を設定することもできます。
Tabキーを押してそのタブストップに移動してそのまま入力すると、プレースホルダーテキスト部分は上書きモードになって書き換えられます。

```
${key: value}
```
- key: タブストップで飛ぶ順番
- value: プレースホルダーテキスト

また、プレースホルダーは以下のようにネストすることもできます。

```
${1:オラは ${2:野原} ${3:しんのすけ} ダゾ。}
```
この場合

1. スニペット出力時は「オラは 野原 しんのすけ ダゾ。」のテキスト全体にカーソルが当たっている状態です。
2. 1回tabを押すと、「野原」というテキストにカーソルが当たります。
3. 2回tabを押すと、「しんのすけ」というテキストにカーソルが当たります。

### タブストップの選択肢を設定する
Tabキーを押してそのタブストップに移動したときに選択できる、選択肢を設定できます。
書式は以下です。

- key: タブストップの順番
- value1, value2..：選択肢（複数可能）

```
${key |value1,value2,value3|}
```
この場合、スニペットを呼び出した際にvalue1,2..がドロップダウンで選択できるようになります。

以下はCSSでレスポンシブのサイズを選択肢で入力するスニペットです。

1. 最初の選択肢で 「~以上」か「~以下の場合」かを選択。
2. 2つ目の選択肢で 境界になる値を選択。

```
"selectMediaQuery": {
	"prefix": "@media",
	"body": [
		"@media(${1|min,max|}-width:${2|1024,768,480,375|}px){",
		"$3",
		"};"
	],
	"description": "メディアクエリの指定"
}
```
このように、あらかじめ入力するパターンが決まっているときに便利です。

## 4_変数

### 4_1組み込み変数

スニペット内で組み込み変数を使用でき、これにより頻出するテキストの自動入力、編集することができます。
組み込み変数で扱うことができるものは下記です。

- ファイル名などのメタ情報
- クリップボード内や現在選択中の文字列
- 現在時刻などのタイムスタンプ
- ブロックコメントの先頭・末尾


これらを活用することで、コーディングや議事録、記事の編集などを非常に効率化することができます。

### 4_2 変数_メタ情報系

以下の変数はファイル名や選択しているテキストなどを編集する組み込み変数です。

|変数|内容|
|---|---|
| TM_SELECTED_TEXT | 現在選択されているテキストまたは空の文字列 |
| TM_CURRENT_LINE | 現在の行の内容 |
| TM_CURRENT_WORD | カーソルの下の単語の内容または空の文字列 |
| TM_LINE_INDEX | ゼロインデックスベースの行番号 |
| TM_LINE_NUMBER | ワンインデックスベースの行番号 |
| TM_FILENAME | 現在のドキュメントのファイル名 |
| TM_FILENAME_BASE | 現在のドキュメントの拡張子なしのファイル名 |
| TM_DIRECTORY | 現在のドキュメントのディレクトリ |
| TM_FILEPATH | 現在のドキュメントの完全なファイルパス |
| RELATIVE_FILEPATH | 現在のドキュメントの（開いているワークスペースまたはフォルダーに対する）相対ファイルパス |
| CLIPBOARD | クリップボードの内容 |
| WORKSPACE_NAME | 開いているワークスペースまたはフォルダーの名前 |
| WORKSPACE_FOLDER | 開いたワークスペースまたはフォルダーのパス |


- CLIPBOARD ：クリップボードの内容
- TM_SELECTED_TEXT：TM_SELECTED_TEXT
- TM_FILENAME_BASE：開いているワークスペースまたはフォルダーの名前

使用用途は人それぞれですが、自分のようなWeb制作者視点だとこれらをよく使いますね。

### 4_3 変数_日時
日時を出力する組み込み変数配下です。
出力される値は 日本時間で 2021年 9/19(日) 午後2時23分15秒の場合です。

|変数|内容|出力される値|
| --- | --- | --- |
|CURRENT_YEAR| 現在の年| 2021 |
|CURRENT_YEAR_SHORT| 現在の年の下2桁| 21 |
|CURRENT_MONTH| 2桁の月| 09 |
|CURRENT_MONTH_NAME| 月のフルネーム| 9 |
|CURRENT_MONTH_NAME_SHORT| 月の短い名前| 9 |
|CURRENT_DATE| 月の日| 19 |
|CURRENT_DAY_NAME| 曜日の名前| 日曜日 |
|CURRENT_DAY_NAME_SHORT| 曜日の短い名前| 日 |
|CURRENT_HOUR| 24時間形式の現在の時間| 14 |
|CURRENT_MINUTE| 現在の分| 23 |
|CURRENT_SECOND| 現在の秒| 15 |
|CURRENT_SECONDS_UNIX| Unixエポックからの秒数| 1632028995 |

記事録や日報をドキュメント形式で作っている（下書きしている）方はこれらを活用してフォーマットを作ると、無駄な入力が減るかもしれません。

### 4_4 変数_ブロックコメント
行またはブロックのコメントを挿入する場合の変数はこちらです。
**※以下はScssの場合です。**

|変数|内容|出力される値|
| --- | --- | --- |
|BLOCK_COMMENT_START| 複数行のコメントアウトの開始 |  /* |
|BLOCK_COMMENT_END| 複数行のコメントアウトの終了 | */ |
|LINE_COMMENT| 1行のコメントアウトの開始 | // |

こちらの変数を使うメリットとして、同じスニペットの記述を別の言語でも使いまわすことができます。

例えば以下のような見出し的なコメントアウトを作りたい時は、以下のスニペットをscss.jsonやjavascript.jsonで使いまわすことができます。

複数行の見出しコメント

```
"blockCommentHedding": {
	"prefix": "//",
	"body": [
		"$BLOCK_COMMENT_START ========================",
		"	$1",
		"======================== $BLOCK_COMMENT_END"
	],
	"description": "複数行コメントアウト見出し (大)"
},
```

出力されるスニペット

```
/* ========================

======================== */
```

1行の見出しコメント

```
"lineCommentHedding": {
	"prefix": "//",
	"body": [
		"$LINE_COMMENT ========================",
		"$LINE_COMMENT	$1",
		"$LINE_COMMENT ========================"
	],
	"description": "1行コメントアウト見出し (大)"
}
```

出力されるスニペット

```
// ========================
//
// ========================
```

### 4_5 プレースホルダー変換
プレースホルダーの変換により、次のタブストップに移動するときにプレースホルダーに挿入されたテキストを変更できます。
挿入されたテキストは正規表現と照合され、指定された置換形式のテキストに置き換えられます。

以下は、とある文字列をクリップボードに格納した状態で、テキストの変更を行う一例です。

>「..Hello-World」とハローワールド

|例|出力|説明|
|---|---|---|
|"${CLIPBOARD/[\\.]/_/}",|最初の「.」を「_」に置換|「_.Hello-World」とハローワールド
|"${CLIPBOARD/[\\.-]/_/g}",| 「.」と「-」を「_」に置換|「__Hello_World」とハローワールド|
|"${CLIPBOARD/(.*)/${1:/upcase}/}",|すべて大文字に変更|「..HELLO-WORLD」とハローワールド|
|"${CLIPBOARD/(.*)/ ${1:/downcase}/}",|すべて小文字に変更|「..hello-world」とハローワールド|
|"${CLIPBOARD/[^0-9^a-z]//gi}"|英数字以外の文字を削除|HelloWorld|

## 5_使用例_HTML

### 5_1 使用例
以下はWEB制作者の自分視点で、登録しているスニペットの一部です。
使えるものがあれば使って下さい。

## HTML

以下は .html形式で使えるスニペットです。
内容はお好みで変えて下さい。

- 複数行コメントアウト見出し (大)

```
"blockCommentHedding": {
	"prefix": "//1",
	"body": [
	"$BLOCK_COMMENT_START ========================",
	"	$1",
	"======================== $BLOCK_COMMENT_END"
	],
	"description": "複数行コメントアウト見出し (大)"
},
```
- 選択した部分を クリップボードの内容 + startとend付きのコメントアウトで包む

```
"commentWrap": {
	"prefix": "//sd",
	"body": [
	"$BLOCK_COMMENT_START [ここから] $CLIPBOARD $BLOCK_COMMENT_END",
	"$TM_SELECTED_TEXT",
	"$BLOCK_COMMENT_START [ここまで] $CLIPBOARD $BLOCK_COMMENT_END"
	],
	"description": "選択した部分をstartとend付きのコメントアウトで包む"
},
```

### 5_2 モジュール

- よくあるハンバーガーメニュー


```
"btnTrigger": {
  "prefix": "cbtntrigger",
  "body": [
    "<!-- HTML ハンバーガーメニュー -->",
    "<div class=\"${1:btn-trigger}\" id=\"${2:btnTrigger}\">",
    "    <span></span>",
    "    <span></span>",
    "    <span></span>",
    "</div>",
    "",
    "/* CSS ハンバーガーメニュー ==========================*/",
    ".${1:btn-trigger} {",
    "    position: relative;",
    "    width: 50px;",
    "    height: 44px;",
    "    cursor: pointer;",
    "    display: inline-block;",
    "    transition: all 0.5s;",
    "    box-sizing: border-box;",
    "    span {",
    "        position: absolute;",
    "        left: 0;",
    "        width: 100%;",
    "        height: 4px;",
    "        background-color: #fff;",
    "        border-radius: 4px;",
    "        display: inline-block;",
    "        transition: all 0.5s;",
    "        box-sizing: border-box;",
    "        &:nth-of-type(1) {",
    "            top: 0;",
    "        }",
    "        &:nth-of-type(2) {",
    "            top: 20px;",
    "        }",
    "        &:nth-of-type(3) {",
    "            bottom: 0;",
    "        }",
    "    }",
    "}",
    "",
    "#${2:btnTrigger}.is-active span{",
    "    &:nth-of-type(1) {",
    "        -webkit-transform: translateY(20px) rotate(-315deg);",
    "        transform: translateY(20px) rotate(-315deg);",
    "    }",
    "    &:nth-of-type(2) {",
    "        opacity: 0;",
    "    }",
    "    &:nth-of-type(3) {",
    "        -webkit-transform: translateY(-20px) rotate(315deg);",
    "        transform: translateY(-20px) rotate(315deg);",
    "    }",
    "}",
    "",
    "#${2:btnTrigger}.active span{",
    "    &:nth-of-type(1) {",
    "        -webkit-transform: translateY(20px) rotate(-315deg);",
    "        transform: translateY(20px) rotate(-315deg);",
    "    }",
    "    &:nth-of-type(2) {",
    "        opacity: 0;",
    "    }",
    "    &:nth-of-type(3) {",
    "        -webkit-transform: translateY(-20px) rotate(315deg);",
    "        transform: translateY(-20px) rotate(315deg);",
    "    }",
    "}",
    "",
    "",
    "",
    "",
    "/* JQuery ハンバーガーメニュー ==========================*/",
    "$(function () {",
    "    $('#${2:btnTrigger}').on('click', function () {",
    "        $(this).toggleClass('is-active');",
    "        return false;",
    "    });",
    "});"
  ],
  "description": "btnTrigger"
}
```

- 選択範囲をdivの .〇〇wrapper or .〇〇innerで包む


```
"wrapDivInnner": {
	"prefix": "lwrap",
	"body": [
		"<div class=\"l-${1|inner,wrapper|}\">",
			"${2:$TM_SELECTED_TEXT}",
		"</div>"
	]
},
```


- youtubeの読み込み


```
"youtubeWrapper": {
	"prefix": "youtube",
	"body": [
	  "<!-- ユーチューブのサイズ変更用のwrapper -->",
	  "<div class=\"youtube_wrapper\">",
	  "    <!-- [ここから]ユーチューブ本体 -->",
	  "",
	  "    <!-- [ここまで]ユーチューブ本体 -->",
	  "</div>",
	  "",
	  "// 埋め込みYouTube ===========================",
	  ".youtube_wrapper {",
	  "    margin: 0 auto;",
	  "    position: relative;",
	  "    padding-top: 56.25%;",
	  "    width: 70%;",
	  "    .iframe_youtube {",
	  "        position: absolute;",
	  "        top: 0;",
	  "        left: 0;",
	  "        border: none;",
	  "        width: 100%;",
	  "        height: 100%;",
	  "    }",
	  "}",
	  ""
	],
	"description": "youtube　の埋め込み"
  },
```

- slick slider 雛形(HTML + JS)

```
"slickSlider": {
	"prefix": "slick",
	"body": [
		"<ul class=\"$1-slider\">",
			"<li class=\"$1-slider__item\"><img alt=\"\" src=\"$2\" /></li>",
		"</ul>",
		"$('.$1-slider').slick({ //{}を入れる",
			"autoplay: true, //「オプション名: 値」の形式で書く",
			"autoplaySpeed: 7000, // 自動再生のスライド切り替えの時間を設定",
			"dots: true, //複数書く場合は「,」でつなぐ",
			"arrows: false, // 左右の矢印を表示",
			"infinite: true,　　　　//スライドのループ",
			"pauseOnHover: false, //ホバーしたときにスライドを一時停止しない　",
			"fade: true,",
			"dotsClass: '$1-slider-indicator' // ドットのクラス名を変更",
		"});"
	],
	"description": "slick sliderの雛形 html + js"
},
```

### 5_3 CDN読み込み

- JQuery CDN 読み込み


```
"scriptJQuery": {
	"prefix": "jq",
	"body": [
		"<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.minjs\"></script>",
	],
	"description": "JQuery読み込み"
},
```

- Bootstrap CDN 読み込み


```
"bootStrapCDN": {
	"prefix": "link",
	"body": [
	"<!-- Bootstrap CSS -->",
	iJTQUOhcWr7x9JvoRxT2MZw1T\" crossorigin=\"anonymous\">"
	],
	"description": "Bootstrap読み込み"
}
```

- Vue.jsのCDN 読み込み


```
"vueJsCDN": {
	"prefix": "cdnvue",
	"body": [
		"<!-- 開発バージョン、便利なコンソールの警告が含まれています -->",
		"<script src=\"https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js\"></script>"
	],
	"description": "Vue.jsのCDN 読み込み"
}
```

- Font awesome CDN 読み込み


```
"fonfAwsomeCDN": {
	"prefix": "link",
	"body": [
		"<!-- Font awesome CDN -->",
		"<link href=\"https://use.fontawesome.com/releases/v5.6.1/css/all.css\"rel=\"stylesheet\">"
	],
	"description": "Font awesome CDN 読み込み"
}
```

- slick sliderの CDN 読み込み


```
"slickSliderCDN": {
  "prefix": "cdnslick",
  "body": [
    "<!-- slick CDN CSS -->",
    "<link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.css\">",
    "<link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick-theme.css\">",
    "<!-- slick CDN JS -->",
    "<script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.min.js\"></script>"
  ],
  "description": "slickSliderCDN"
}
```

### 5_4 WordPress関数

- WordPress getfield関数


```
"getField": {
	"prefix": "wpgetfield",
	"body": [
		"<!-- [START]$1 -->",
		"<?php if (get_field('$2')) : ?>",
		"<?php the_field('$2'); ?>",
		"<?php endif; ?>",
		"<!-- [END]$1 -->"
	],
	"description": "カスタム投稿の取得と出力"
},
```

## 6_使用例_Scss

### 6_1 便利系

- 選択中のテキストをスニペットにする


  ```
  	"makeSnipet": {
		"prefix": "snipet",
		"body": [
			"\"${1:snipetName}\": {",
			"\"prefix\": \"${2:snipetTrigger}\",",
			"\"body\": [",
			"        \"$TM_SELECTED_TEXT\"",
			"],",
			"\"description\": \"${3:スニペットの説明（日本語ok）}\"",
			"}"
		],
		"description": "選択中のテキストをスニペットに格納する"
	},
  ```

- 変数とmixinのファイルをインポート


  ```
	"importVarMixin": {
		"prefix": "@import",
		"body": [
		  "@import \"_variables\";",
		  "@import \"_mixin\";"
		],
		"description": "変数とmixinのファイルをインポート"
	  }
  ```

- 空の擬似要素

```
  "emptyPseudoelement": {
		"prefix": "&::",
		"body": [
		  "    &::${1|before,after|}{",
		  "        content: \"\";",
		  "        position: absolute;",
		  "    }"
		],
		"description": "空の疑似要素"
	  },
```

### 6_2 変数

- SNSのカラーコード変数

```
  	"colorSns": {
		"prefix": "sns",
		"body": [
			"\\$colorSnsTwitter: #1da1f2;",
			"\\$colorSnsLine: #00b900;",
			"\\$colorSnsFaceBook: #1877f2;",
			"\\$colorSnsYouyTube: #da1725;",
			"\\$colorSnsTwitch: #6441a4;"
		],
		"description": "SNSのカラーコード変数"
	}
```

- マテリアルデザイン box-shadow変数

```
	  "materialBoxShadow": {
		"prefix": "$box-shadow",
		"body": [
		  "// Googleのbox-shadow",
		  "boxShadowGoogle1: 0 2px 5px rgba(0,0,0,0.26)",
		  "boxShadowGoogle2: 0 2px 10px rgba(0,0,0,.2)",
		  "",
		  "// TopCoderのbox-shadow",
		  "boxShadowTopCoder: 0 1px 6px rgba(0,0,0,.2);",
		  "",
		  "// Feedly のbox-shadow",
		  "boxShadowFeedly1: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);",
		  "boxShadowFeedly2: 0 10px 20px rgba(0,0,0,0.12), 0 6px 6px rgba(0,0,0,0.16);",
		  "",
		  "// Z-levels",
		  ".z-depth-0 {",
		  "  box-shadow: none !important;",
		  "}",
		  ".z-depth-1{",
		  "  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);",
		  "}",
		  ".z-depth-1-half{",
		  "  box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18), 0 4px 15px 0 rgba(0, 0, 0, 0.15);",
		  "}",
		  ".z-depth-2{",
		  "  box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);",
		  "}",
		  ".z-depth-3{",
		  "  box-shadow: 0 12px 15px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19);",
		  "}",
		  ".z-depth-4{",
		  "  box-shadow: 0 16px 28px 0 rgba(0, 0, 0, 0.22), 0 25px 55px 0 rgba(0, 0, 0, 0.21);",
		  "}",
		  ".z-depth-5{",
		  "  box-shadow: 0 27px 24px 0 rgba(0, 0, 0, 0.2), 0 40px 77px 0 rgba(0, 0, 0, 0.22);",
		  "}"
		],
		"description": "マテリアルデザインのbox-shadow"
	  }
```

### 6_3 スタイル系

- 定番のfont-familyの変数


  ```
	"varFontFamiry": {
		"prefix": "\\$fontfamiry",
		"body": [
			"\\$fontFamilyYuGo: \"游ゴシック体\", \"YuGothic\", \"游ゴシック\", \"Yu Gothic\", \"ヒラギノ角ゴ Pro W3\", \"Hiragino Kaku Gothic Pro\", \"メイリオ\", \"Meiryo\", sans-serif;",
			"\\$fontFamilyHiraGo: \"ヒラギノ角ゴ Pro W3\", \"Hiragino Kaku Gothic Pro\", \"メイリオ\", \"Meiryo\", sans-serif;",
			"\\$fontFamilyYuMin: \"游明朝\", \"YuMincho\", \"ヒラギノ明朝 Pro W3\", \"Hiragino Mincho Pro\", \"ＭＳ Ｐ明朝\", \"MS PMincho\", serif;",
			"\\$fontFamilyHiraMin: \"ヒラギノ明朝 Pro W3\", \"Hiragino Mincho Pro\", \"ＭＳ Ｐ明朝\", \"MS PMincho\", serif;",
			"\\$fontFamilyMeiryo: \"メイリオ\", \"Meiryo\", \"ヒラギノ角ゴ Pro W3\", \"Hiragino Kaku Gothic Pro\", \"ＭＳ Ｐゴシック\", sans-serif;",
			"\\$fontFamilyArial: Arial,Helvetica,Verdana,Hiragino Kaku Gothic ProN,-apple-system,BlinkMacSystemFont,メイリオ,MS PGothic,sans-serif;"
		],
		"description": "よく使うfont-familyの変数"
	},
  ```

### 6_4 レイアウト系

- 最初の要素以降に にmargin-topを付与

```
 	"notFirstChildMarginTop": {
		"prefix": "&:not(:first-child){",
		"body": [
			"&:not(:first-child){",
			"margin-top: ${1:10px};",
			"}"
		],
		"description": "not(:first-child)にmargin-top"
	}
```

- pddingの分を中に狭めるCSS

```
	"allBoxSizingBorderBox": {
		"prefix": "boxsizing",
		"body": [
			"* {",
			"box-sizing: border-box;",
			"}"
		],
		"description": "pddingの分を中に狭めるCSS"
	}
```

- positionを用いた 縦方向の中央寄せ

```
	"centerY": {
		"prefix": "cy",
		"body": [
			"position: ${1|absolute,relative|};",
			"top: 50%;",
			"transform: translateY(-50%);"
		],
		"description": "positionを用いた 縦方向の中央寄せ"
	},
```

- positionを用いた 横方向の中央寄せ

```
	"centerX": {
		"prefix": "cx",
		"body": [
			"position: ${1|absolute,relative|};",
			"left: 50%;",
			"transform: translateX(-50%);"
		],
		"description": "positionを用いた 横方向の中央寄せ"
	},
```

- positionを用いた 上下 左右 中央寄せ

```
	"positionXYCenter": {
		"prefix": "cxy",
		"body": [
			"position: ${1|absolute,relative|};",
			"left: 50%;",
			"top: 50%;",
			"transform: translate(-50%, -50%);"
		],
		"description": "positionを用いた 上下 左右 中央寄せ"
	},
```
- flexを用いた 上下 左右 中央寄せ

```
	"flexCenter": {
		"prefix": "cxy",
		"body": [
			"display: flex;",
			"justify-content: center;",
			"align-items: center;"
		],
		"description": "flexを用いた 上下 左右 中央寄せ"
	}
```

- gridを用いた 上下 左右 中央寄せ

```
	"gridXYCenter": {
		"prefix": "cxy",
		"body": [
			"display: grid;",
			"place-items: center;"
		],
		"description": "gridを用いた 上下 左右 中央寄せ"
	},
```

- 横並び３枚のカードの幅

```
	"3cardWidth": {
		"prefix": "width: calc;",
		"body": [
			"width: calc((100% - ($1px * 2))/ 3 - 1px);"
		],
		"description": "横並び３枚のカードの幅"
	}
```

- displayFlex, SpaceBetween

```
	"displayFlexSpaceBetween": {
		"prefix": "disfleb",
		"body": [
		  "display: flex;",
		  "justify-content: space-between;"
		],
		"description": "displayFlex, SpaceBetween"
	  },
```

### 6_5 コンポーネント系

- ボタンのリセットCSS
  
```
  "buttonReset": {
		"prefix": ".btn",
		"body": [
		  ".btn {",
		  "    display: inline-block;",
		  "    padding: 0.6em 2em;",
		  "    margin: 0 0 1em;",
		  "    background-image: none;",
		  "    background-color: #4caf50;",
		  "    color: #fff;",
		  "    text-decoration: none;",
		  "    border: none;",
		  "    border-radius: 0;",
		  "    cursor: pointer;",
		  "    -webkit-appearance: none;",
		  "    box-shadow: 1px 1px 3px 0 rgba(0, 0, 0, 0.2);",
		  "    position: relative;",
		  "}",
		  ".btn:hover .btn:focus {",
		  "    outline: none;",
		  "}",
		  ".btn::-moz-foucus-inner {",
		  "    padding: 0;",
		  "    border: none;",
		  "}"
		],
		"description": "ボタンのリセットCSS"
	  }
```

### 6_6 メディアクエリ系

- メディアクエリの指定


```
"selectMediaQuery": {
	"prefix": "@media",
	"body": [
		"@media(${1|min,max|}-width:${2|1024,768,480,375|}px){",
		"$3",
		"};"
	],
	"description": "メディアクエリの指定"
}
```

### hover時のトラジション

- hoverで 透過させる


```
    "hoverOpacity": {
      "prefix": "&:hover",
      "body": [
        "opacity: 1;",
        "transition: opacity 1{1:0.5s};",
        "&:hover {",
        "  opacity: 2{2:0.7};",
        "}"
      ],
      "description": "hoverで 透過させる"
    }
```

- hoverで 拡大


```
 "hoverScale": {
 	"prefix": "&:hover-scale",
 	"body": [
 	  "transition: scale 0.5s;",
 	  "&:hover {",
 	  "    transform: scale(1.2);",
 	  "}"
 	],
 	"description": "hoverで拡大"
   }
```

- hoverで 上昇する


```
"hovertranslateY": {
  "prefix": "&:hover-translateY",
  "body": [
    "transition: all 0.5s;",
    "&:hover {",
    "    transform: translateY(-${1:5px});",
    "    box-shadow: 0 7px 14px rgba(50,50,93,.1), 0 3px 6px rgba(0,0,0,.08);",
    "}"
  ],
  "description": "hovertranslateY"
}
```

### 6_8 コメントアウト

- 大見出し (コンパイル後残る)


```
	"comentOut1": {
		"prefix": "//1",
		"body": [
			"/* =============================================",
			" $1",
			"============================================= */"
		],
		"description": "大見出し（コンパイル後残る）"
	},
```

- 中見出し (コンパイル後残る)

```
	"comentOut2": {
		"prefix": "//2",
		"body": [
			"/* $1",
			"// ====================================================*"
		],
		"description": "中見出し（コンパイル後残る）"
	},
```

- 大見出し (コンパイル後残らない)

```
	"comentOut1l": {
		"prefix": "//1",
		"body": [
			"// =============================================",
			"// $1",
			"// ============================================="
		],
		"description": "大見出し（コンパイル後残らない）"
	}
```

- 中見出し (コンパイル後残らない)

```
	"comentOut2l": {
		"prefix": "//2",
		"body": [
			"// $1",
			"// ===================================================="
		],
		"description": "中見出し（コンパイル後残らない）"
	},
```

## 7_終わり

### 7_1 終わりに
「汚ったねえ書き方だなあ」とか、この記事を書きながら自分で書いていましたが、自分の作業がどんどん効率化されていくことに喜びを感じながら、これからも改良を続けていきたいと思います。
もっといい使い方を知っている方いらっしゃいましたら、ぜひ色々アドバイスいただけると嬉しいです。

長い記事でしたが、皆さんお疲れ様でした！

良いコーディングライフを！

### 参考にしたサイト

- [（公式）Snippets in Visual Studio Code](https://code.visualstudio.com/docs/editor/userdefinedsnippets#_builtin-snippets)
- [snippet generator](https://snippet-generator.app/?description=&tabtrigger=&snippet=&mode=vscode)
- [みどりみちのブログ](https://midorimici.com/posts/vscode-user-snippets)
- [tk3118’s blog](https://tk3118.hatenablog.com/entry/2020/01/08/152411)