図解あり！cssのcalc関数で要素を中央配置する方法

# 先週は、a-blog cmsの脆弱性対応をしました
先週は、**a-blog cms に重大な脆弱性が見つかった**ことで、その対応をしていました。
下記が詳細な内容です！**もしまだ未対応の方は下記を参照ください**:point_down:

https://developer.a-blogcms.jp/blog/news/security-update202503.html

https://developer.a-blogcms.jp/blog/news/entry-4197.html

弊社では、基本的には、上記記事にある、**「影響を受けるバージョン」以下のドメインを、最新版までオンラインアップデートしましょうという方針**で脆弱性対応をしました。全てパッチバージョンのアップデートでした。


# さて、今回は、関数に関して勉強しようと思います。
Q.下記は何を表すでしょうか？
**left: calc(50% - 150px);**

A.これは、**幅が300pxの要素を親要素の中央に配置される**(左端を親要素の中央から150px左へずらす)ことを意味します。
ある要素を、親要素の横軸中央に配置したいときは、position:absolute;している場合にはmargin:0 auto;や flexによる中央配置ができず、css内の計算によって数値を算出する必要があります。
right: calc(50% + 150px);(右端を親要素の中央から150px右へずらす)でも同じ事ができます。

私の場合、親要素のグローバルナビゲーションがレスポンシブで、それをホバーしたときに出てくる子要素のナビゲーションは固定値の場合があり、子要素のナビゲーションを親要素の中央配置したい場合に使用しました（文字にするとややこしい）。:slight_smile:
図にすると以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/e8f72130-1691-4699-9d14-7cd892c4dbd1.png)


## calc、どんなときに使う？
具体的に、どんなときに使えるのかを調べてみました。:writing_hand:
| 用途	| 具体的なcalc()の例 | 使い方 |
|:-:|:-:|:-:|
幅の計算	| width: calc(100% - 50px);| 親要素の幅から固定値を引く
中央配置	|margin-left: calc(50% - 150px);|中央寄せ
フォントサイズ|	font-size: calc(1rem + 1vw);|画面幅に応じた文字サイズ
グリッド調整|width: calc(33.33% - 10px);|カラムの幅調整
位置調整|left: calc(50% - 200px);|中央に要素を配置

など、色んなところで使えるようですね:bulb:
ちなみに、親要素と子要素の幅に合わせた中央配置について、以下にまとめました。
子要素が可変のときは、calcでの完璧な中央配置は難しいので、
left: 50%; 
transform: translateX(-50%);
で中央配置がおすすめです。
| 親の幅	| 子の幅 | 最適な中央配置方法 |
|:-:|:-:|:-:|
可変	|可変|left: 50%; transform: translateX(-50%);
可変|300px 固定|left: calc(50% - 150px);
固定|可変|left: 50%; transform: translateX(-50%); 


## 実践してみる 
a-blog cmsのUTSUWAテーマで、ナビゲーションの子要素を中央配置してみようと思います。
あ、そういえば、[UTSUWAテーマ](https://theme.a-blogcms.jp/utsuwa/)がイメチェンしていますね！
いつも見慣れたサイトでもメインビジュアルが変わるとがらりと印象が変わりますね。:thumbsup:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/2e7cf2ea-ac8c-5444-ecd1-3008693b8898.png)

余談はさておき、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/619f7a5f-b91f-1095-f77e-7edd746a5e92.png)
UTSUWAのグローバルナビゲーションをhoverすると、子ナビゲーションが出現しますが、以下のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/ab086cc2-03bb-d09c-f7dc-1b952e176c00.png)
この子ナビゲーションを親ナビゲーションの真ん中に表示させたいとき、どうすればいいかを考えてみます。

今回の場合、
.global-nav-item > .global-nav-list（子ナビゲーション）は
position: absolute;　されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/a0d9b613-be0e-44a9-87c8-0c1223911901.png)
なので、display:flex;での中央配置やmargin:0 auto;は使えません。
そうなると、子要素が可変なのか固定なのか？で最適な中央配置方法を検討していきます。
.global-nav-item > .global-nav-list　のwidthをみてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/e68563a0-b704-4870-8f2f-e7d7af4b9195.png)

.global-nav-item > .global-nav-listは、min-width: 14rem;でした。
min-width の場合、子要素の幅が 14rem以上になる可能性があり、正確な中央配置ができなくなります。なので、子要素は可変と判断します。（width: 14rem;なら、left: calc(50% - 7rem); で中央配置可能）
なので、この場合の最適な中央配置方法は、
left: 50%; 
transform: translateX(-50%);
です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/d5cf8b98-dece-4886-8eff-277d16a3ec5f.png)

# さいごに
グローバルナビゲーションの構造に関しては以前、[記事に書きました](https://qiita.com/a_kawasaki/items/d1426fd6ed78b4cf3119)のでそちらをご参考にどうぞ。
今回calcについて勉強し、すこーしだけ関数への苦手意識が減ったかもと思いました。
中央配置で悩まず、要素を思い通りに配置できるように頑張ります:sunny: