【CSS】macOSライクなプログレスバーを作る

# 1. はじめに
macOSをBig Surでは、UIが大きく変更され丸みを帯びたデザインに統一されました。
また、要素のアニメーションも加わり、特に**プログレスバーがなめらかに動くようになった**のが印象的です。

そこで、CSSでも同じようなデザインで、滑らかに動くプログレスバーを作れないかと思い、実装してみました。

# 2. macOSでのプログレスバーとその動きとは？
## A. 進捗の割合がわかる場合
ファイルのコピーやソフトウェアのインストール、ファイルのダウンロードなど進捗の割合を求めることができる場合、滑らかにバーが横に動きます。
例：ファイルのコピー
![2021-10-05 16-24-38-セグメント 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/2d38f86e-fe1a-1580-b46e-58fa4ae964bc.gif)

視覚的に、**加減速運動**をしています。動き初めは加速し、止まるときは減速しているのがわかります。

## B. 進捗の割合がわからない／処理待機中の場合
インストールの準備や、ネットワークへの接続待機など、進捗状況が分からなかったり待機している場合は、色のついた短いバーが左右に移動するのを繰り返します。
例：ネットワーク他機器への接続
![2021-10-05 16-27-44-セグメント 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/e05bedea-89a0-e029-1c56-583ee2ab62bc.gif)


Aと違い、**【ほぼ】減速運動**をしています。動きだしはすぐに加速し、止まるときのみなめらかに減速しているのがわかります。
この記事では単純化のために、**減速運動**を使用します。


# 3. 実装
## A. 進捗の割合がわかる場合
ベースとなるプログレスバーの背景と色付きのバー部分を定義します。
JavaScriptなど動的な数値の変更をしない場合、`width="37%"`のように、幅をそのまま進捗の割合として指定します。

```html:HTML
<div class="main">
    <div class="progress_back">
        <div class="progress_front" width="37%"></div>
    </div>
</div>
```
CSSを使ってスタイルを追加します。色や大きさは適宜変えてください。
`transition: [x]s ease-in-out;`とすることで、要素に変化があった時加減速運動で遷移するようになります。

```css:CSS
.progress_back{
	display: block;
	width: 100%;
	height: 7px;
	background: #ccc;
	position: relative;
	border-radius: 10px;
}
.progress_front{
	display: block;
	width: 0;
	height: 7px;
	background: #e31787;
	position: absolute;
	left: 0;
	top: 0;
	border-radius: 10px;
	transition: 0.5s ease-in-out;
	overflow: hidden;
	}
```

これだけで、Big Surライクな丸みを帯びた色付きのプログレスバーを表示できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/e13c4d3c-d7c8-d82d-a8e6-a726a3e4dceb.png)

### JavaScriptを利用したデモ風景
数値を動的に変え、バーが動く様子を示しています。Big Surっぽい動きができているのではないでしょうか？
![bandicam 2021-10-05 17-01-45-396-セグメント 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/de2a615f-86e0-1330-3efd-dc6d436d8022.gif)


## おまけ：光るアニメーション
プログレスバーが止まったままでは、閲覧者にとっては「今、処理や手続きが進行しているのかどうか」が伝わりにくい場合があります。
そこで、プログレスバーが光るようにして、「今も頑張って処理しています感」を出してみます。
上記のCSSに追加してください。

```css:CSS
.progress_front::before {
    position: absolute;
    content: '';
    display: inline-block;
    top: 0px;
    left: -100%;
    width: 50%;
    height: 7px;
    background-color: #fff;
    animation: shiny-bar 3s linear infinite;
    }
@keyframes shiny-bar {
    0% { transform: translateX(0px); opacity: 0.5; }
    50% { transform: translateX(410%); opacity: 0.5; }
    100% { transform: translateX(410%); opacity: 0.0; }
}
```
光るアニメーションがあれば、「処理が進行中」である演出を行うことができます。
![bandicam 2021-10-05 17-22-59-918.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/064167f6-2317-083e-fa04-835c3e0ee889.gif)


## B. 進捗の割合がわからない／処理待機中の場合
Aと同じように、HTMLとCSSのみで実装できます。

```html:HTML
<div class="main">
    <div class="progress_back">
        <div class="progress_front_unknown"></div>
    </div>
</div>
```
以下のCSSを上記Aのものに追加してください。
色付きのバーの長さは、本来のものよりも長く（プログレスバー全体の50%）しています。

```css:CSS
.progress_front_unknown{
	display: block;
	width: 100%;
	height: 7px;
	background: #ccc;
	position: absolute;
	left: 0;
	top: 0;
	border-radius: 10px;
	transition: 0.5s ease-in-out;
	overflow: hidden;
}
.progress_front_unknown::before {
	position: absolute;
	content: '';
	display: inline-block;
	top: 0px;
	left: -48%;
	width: 50%;
	height: 7px;
	background-color: #e31787;
	animation: bar-unknown 3s ease-out infinite;
	border-radius: 50px;
}
@keyframes bar-unknown {
	0% { transform: translateX(0%); }
	45% { transform: translateX(294%); }
	50% { transform: translateX(294%); }
	98% { transform: translateX(0%); }
	100% { transform: translateX(0%); }
}
```

![bandicam 2021-10-05 17-01-45-396-セグメント 1(1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/3d65d19d-39b7-075c-abef-b14da9e1eeab.gif)


処理が中断していたり、準備中だったりする場合はこのアニメーションを使うとよいかもしれません。