【Blazor】初期のサイドバーをヘッダーメニューに変更する方法

クライアント側の処理もjavascriptを使用しないでC#で書けるようになった「Blazor」(ブレイザー)を必要に迫られて、学習を始めました。

初期段階で作成される画面構成を確認して、ASP.NET MVC5の見た目になれた者としては、
サイドバーだとコンテンツの部分が狭くて見づらい。。
そこで今回は、**Blazorの初期のサイドバーをASP.NET MVC5のようなヘッダーメニュー**に変更する方法をまとめました。

**【Blazor 初期のサイドバー】**
![blazor_sidebar_display.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/1708e84e-f58c-6ed9-cca2-997bd87bb53b.png)

![blazor_sidebar_display-sp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/014a7253-a41a-4a0f-06f3-4c2205de4a46.png)

**【ASP.NET MVC5のヘッダーメニュー】**
![aspnetmvc5_header_display.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/a0e689fb-abe1-2245-3998-4cd6eff948a8.png)

![aspnetmvc5_header_display-sp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/29bedf6b-5cf0-f8dd-1e3b-59f07642f4e4.png)


# 事前準備

## 環境

・Visual Studio Community 2019
・.NET Core SDK 3.0.1

## プロジェクト作成

(1) Visual Studioを起動後、「新しいプロジェクトの作成」を選択する。
![aspnetmvc5_login0.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/e73b83f2-7287-f6cf-4d20-553f1a784e4d.png)

(2) 新しいプロジェクトの作成画面で、「Blazorアプリ」を選択後、「次へ」ボタンをクリックする。
![blazor_side_to_header1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/8ff93139-45a7-9a34-70d1-bffe5231b2cb.png)

(3) プロジェクト名などを設定後、「作成」ボタンをクリックする。
![blazor_side_to_header2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/839540f7-88a9-419f-baa3-9e45784742f7.png)

(4) 「Blazorサーバーアプリ」を選択後、「作成」ボタンをクリックする。
![blazor_side_to_header3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/40887f5e-9016-4d60-38d7-0b1098c83eb0.png)

# ソース修正
## MainLayout.razorの修正

まずは初期のBlazorのレイアウトの構造を見てみましょう。

(1) 全体のレイアウトのソースは、[Shared] →「MainLayout.razor」になります。

![blazor_side_to_header4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/bad2fe4f-f522-0869-b758-0fa0df536ed5.png)

```csharp:MainLayout.razor
@inherits LayoutComponentBase

<div class="sidebar">
    <NavMenu />
</div>

<div class="main">
    <div class="top-row px-4">
        <a href="https://docs.microsoft.com/en-us/aspnet/" target="_blank">About</a>
    </div>

    <div class="content px-4">
        @Body
    </div>
</div>
```

コードを確認すると、以下の構造になっているようです。
※コード上のclass名を画像内に記載しています。

![blazor_sidebar_display2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/4fec3beb-1bbe-b78c-2566-37149a11ef7e.png)

現状、top-rowのdiv要素がヘッダーメニューになっているので、ここを削除後、sidebarのdiv要素をmain内に移動します。
<font color="red">※この記事では分かりやすいように削除はコメントアウトにしています。</font>

```csharp:MainLayout.razor
@inherits LayoutComponentBase

@*
<div class="sidebar">
    <NavMenu />
</div>
*@

<div class="main">
    <div class="sidebar">
        <NavMenu />
    </div>
    @*
    <div class="top-row px-4">
        <a href="https://docs.microsoft.com/en-us/aspnet/" target="_blank">About</a>
    </div>
    *@

    <div class="content px-4">
        @Body
    </div>
</div>
```

## site.cssの修正

(1) [wwwroot] → [css] → [site.css]を選択する。

![blazor_side_to_header5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/cf556ab2-bca1-115a-8990-746717881c85.png)

(2) 以下の部分を修正します。
<font color="red">※以下の/* 追加 */ /* 削除 */　などコメントが記載されている部分。</font>

```css:site.css
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');

html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

a, .btn-link {
    color: #0366d6;
}

.btn-primary {
  color: #fff;
  background-color: #1b6ec2;
  border-color: #1861ac;
}

app {
    position: relative;
    display: flex;
    flex-direction: column;
}

.top-row {
    height: 3.5rem;
    display: flex;
    align-items: center;
    background-color: #000; /* 追加 */
    /*background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);*/ /* 削除 */
}

.main {
    flex: 1;
}

.main .top-row {
    background-color: #f7f7f7;
    /*border-bottom: 1px solid #d6d5d5;*/ /* 削除 */
    /*justify-content: flex-end;*/ /* 削除 */
}

.main .top-row > a {
    margin-left: 1.5rem;
}

.sidebar {
    background-color: #000; /* 追加 */
    /*background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);*/ /* 削除 */
}

.sidebar .top-row {
    background-color: rgba(0,0,0,0.4);
}

.sidebar .navbar-brand {
    font-size: 1.1rem;
}

.sidebar .oi {
    width: 2rem;
    font-size: 1.1rem;
    vertical-align: text-top;
    top: -2px;
}

.nav-item {
    font-size: 0.9rem;
    padding-bottom: 0.5rem;
    display: inline-block; /* 追加 */
}

.nav-item:first-of-type {
    padding-top: 1rem;
}

.nav-item:last-of-type {
    padding-bottom: 1rem;
}

.nav-item a {
    color: #d7d7d7;
    border-radius: 4px;
    height: 3rem;
    /*display: flex;*/ /* 削除 */
    align-items: center;
    line-height: 2.2rem; /* 3rem→2.2remに変更 */
}

.nav-item a.active {
    background-color: rgba(255,255,255,0.25);
    color: white;
}

.nav-item a:hover {
    background-color: rgba(255,255,255,0.1);
    color: white;
}

/* 追加 */
.nav {
    display: inline-block;
}

.content {
    padding-top: 1.1rem;
}

.navbar-toggler {
    background-color: rgba(255, 255, 255, 0.1);
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

@media (max-width: 767.98px) {
    /* 削除 */
    /*
    .main .top-row {
        display: none;
    }
    */
    
    /* 追加 */
    .nav {
        display: flex;
    }
}

@media (min-width: 768px) {
    app {
        flex-direction: row;
    }

    /* 削除 */
    /*
    .sidebar {
        width: 250px;
        height: 100vh;
        position: sticky;
        top: 0;
    }
    /* 追加 */
    .sidebar {
        height: auto;
        top: 0;
        display: flex;
        align-items: center;
    }

    .main .top-row {
        position: sticky;
        top: 0;
    }

    .main > div {
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }

    .navbar-toggler {
        display: none;
    }

    .sidebar .collapse {
        /* Never collapse the sidebar for wide screens */
        display: block;
    }
}
```

## 動作確認

それでは、動作確認をしていきましょう！
まずはパソコン版での表示です。

![blazor_sidebar_display_edit1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/059b5975-cb43-7154-5aea-da31ce8be24b.png)

MVCの時みたいに、背景色が黒のヘッダーメニューが表示されました。
続いて、ブラウザのサイズを小さくして、スマフォでの表示を確認します。

![blazor_sidebar_display_edit2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634715/53640a53-9015-5dfb-968f-fa1302165f1d.png)

こちらも無事に、ハンバーガーメニューが表示され、「三」をクリックすることでメニュー表示ができました！

# まとめ

ということで、今回はBlazorの初期で表示されるサイドバーをヘッダーメニューに変更する方法をまとめました。
必要な作業は以下、2点になります。

**１．MainLayout.razorのコードを修正する**
**２．cssを修正して、デザインを修正する。（今回は初期から入っているsite.cssを修正）**

ハンバーガーメニューのデザインなど細かいデザインまでは再現できていませんが、
黒背景でヘッダーメニューにすることはできました！
僕みたいにヘッダーメニューにしたいと思われた方は、マネしてみてください(^^)

それでは、今回も最後までお読みいただきありがとうございました！