LoginSignup
12
6

More than 3 years have passed since last update.

流行りのReactを使って,レスポンシブな(Qiita)ヘッダーを作成してみる。

Last updated at Posted at 2020-09-07

はじめに

React記事の一環として、レスポンシブデザインのヘッダーを作成してみます。今回はわかりやすいように、Qiitaと同じヘッダーを作成していきます。

Qiitaのようなヘッダーのデザインもよくありますよね。
qiita__navbar-3.png

ソースコード:https://github.com/TokyoProgramming/qiita__navbar

  • この記事で学べる事
    • ReactでのレスポンシブWebデザイン
    • MediaQueries
    • よくあるヘッダーのデザイン方法
    • Material-UI

1.React構造

  • Componentsディレクトリ内
    • Header.js
    • Header.css

以下のようなシンプルな構造にしています。

qiita-react-structure.png

2.Material-UI

それでは今回使用する。Material-UIをインストールしていきます。

npm install @material-ui/core
npm install @material-ui/icons

これで、Material-uiのアイコンを使用できます。
今回使用するMaterial-uiのアイコンたちです。

import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';
import SearchIcon from '@material-ui/icons/Search';
import BeenhereIcon from '@material-ui/icons/Beenhere';
import CreateIcon from '@material-ui/icons/Create';
import NotificationsNoneIcon from '@material-ui/icons/NotificationsNone';
import {Avatar} from "@material-ui/core";

3.ヘッダー 左側

Header.js
import React from 'react';
import './Header.css';

//ここにMaterial-uiをインポートする


function Header() {
    return (
        <div className="header">
            <div className='headerLeft'>
                <div className='headerLeft__object'>
                    <h1>Qiita</h1>
                    <ArrowDropDownIcon />
                </div>
                <div className='headerLeft__object'>
                    <div className='header__community'>
                        <p>コミュニティ</p>
                        <ArrowDropDownIcon />
                    </div>
                </div>
                <div className='headerLeft__object'>
                    <div className='search__form'>
                        <SearchIcon />
                        <input
                            className="headerLeft__input"
                            placeholder="キーワードを入力"

                        />
                    </div>
                    <div className="search__form__media">
                        <SearchIcon />
                    </div>
                </div>
            </div>

            <div className='headerRight'>

                 ...

            </div>
        </div>
      )
 }

 export default Header


スタイリング何もしないとこのような結果になります。
悲惨です。外人が見たら、catastropheと叫ぶことでしょう。

qiita__headerLeft-1.png

ヘッダー左側cssスタイリング

まずは、親要素の.headerのスタイリングからです。

.header{
    display: flex;
    margin-top: 0;
    position: sticky;
    background-color: #55c500;
    width: 100vw;
    height: 60px;
    justify-content: space-around;
}

qiita__headerLeft-2.png

なんとも言えませんね。。。
親要素に収まってもいないし。。
どんどんいきます。

.headerLeft {
    display: flex;
}

qiita__headerLeft-3.png

Header.css
.headerLeft__object > h1{
    margin: 0 10px 5px 3px;
    color: white;
    cursor: pointer;
}
.headerLeft__object > .MuiSvgIcon-root{
    border: 1px solid #3a8a00;
    font-size: 15px !important;
    color: white!important;
    background-color: #3a8a00!important;
    padding: 2px;
    border-radius: 5px;

}
.headerLeft__object > .MuiSvgIcon-root:hover{
    border: 1px solid #3a8a00;
    font-size: 15px !important;
    color: #b8dfdf!important;
    background-color: #337600!important;
    padding: 2px;
    border-radius: 5px;
    cursor: pointer;
}

qiita__headerLeft-4.png

headerLeft__object > .MuiSvgIcon-rootで、Material-UIのアイコンを指定できます。
!importantは、material-uiなどのアイコンはもともとアイコンのスタイルが設定されているため、こちらのスタイルが"重要"であることを伝えるために、記述しなければなりません。

左側から順番に仕上がりつつあります。

Header.css
//コミュニティアイコン
.header__community{
    display: flex;
    align-items: center;
}
.header__community > .MuiSvgIcon-root {
    color: #3a8a00!important;
    cursor: pointer;
}
.header__community > p{
    color: white;
    font-size: 12px;
    cursor: pointer;
}
.header__community > .MuiSvgIcon-root:hover {
    color: white !important;
}
@media screen and (max-width: 990px){
    .header__community {
        display: none
    }
}

ここで、mediaQueriesがでてきましたが、恐れることはありません。
990pxより小さくなったら、今、仕上げた コミュニティ+アイコンを表示しなくする設定です。
モニターが大きいデバイスを持っている方は、Qiitaで試してみればわかりますが、横幅を小さくしていくと、コミュニティ+アイコンが表示されなくなります。

qiita__headerLeft-5.png

qiita__headerLeft-5-2.png

Header.css
//検索フォーム
.search__form {
    display: flex;

    border: 1px solid coral;
    background-color: white;
    padding: 5px;
    border-radius: 5px;
}
.search__form > .MuiSvgIcon-root{
    color: #baaeaa!important;
    font-size: 20px !important;
}

.search__form > input {
    border: none;
}
.search__form > input:focus{
    outline-width: 0;
}
.search__form > input::placeholder{
    color: #baaeaa;
    font-size: 12px;
}

.search__form:hover{
    display: flex;
    border: 2px solid black;
    background-color: white;
}


@media screen and (max-width: 990px){
    .search__form {
        display: none
    }
    .search__form__media > .MuiSvgIcon-root{
        color: white!important;
        font-size: 23px !important;
        margin-top: 5px;
    }
}
@media screen and (min-width: 991px) {
    .search__form__media > .MuiSvgIcon-root{
        display: none;
    }
}

検索フォームの作り方はこちらの記事で詳しく書いているのこちらでは割愛します。

流行りのReactでFlexboxを利用して、検索フォーム内にアイコンを入れてみる。
https://qiita.com/Yusuke_Yoshioka/items/5d0ba245b70e524e755e

qiita__headerLeft-6.png

ここまでくるとヘッダーの左側は完成しました。
残り半分頑張っていきます。

4.ヘッダー右側

Header.js
import React from 'react';
import './Header.css';


function Header() {
    return (
        <div className="header">
            <div className='headerLeft'>

                ...

            </div>
//ここから追加
            <div className='headerRight'>
                <div className='headerRight__object'>
                    <BeenhereIcon />
                    <p className="headerRight__p">ストック一覧</p>
                </div>
                <div className='headerRight__object'>
                    <div className='headerRight__publish'>
                        <CreateIcon />
                        <p>投稿する</p>
                        <ArrowDropDownIcon />
                    </div>
                </div>
                <div className='headerRight__object'>
                    <div className='headerRight__notification'>
                        <NotificationsNoneIcon />
                        <p>0</p>
                    </div>
                </div>
                <div className='headerRight__object'>
                    <div className='headerRight__avatar'>
                        <Avatar />
                        <ArrowDropDownIcon />
                    </div>
                </div>


                {/* Media   */}
                <div className='headerRight__object__media'>
                    <BeenhereIcon />
                </div>
                <div className='headerRight__object__media'>
                    <div className='headerRight__notification'>
                        <NotificationsNoneIcon />
                        <p>0</p>
                    </div>
                </div>
                <div className='headerRight__object__media'>
                    <div className='headerRight__avatar'>
                        <Avatar />
                        <ArrowDropDownIcon />
                    </div>
                </div>


            </div>
        </div>
      )
 }

 export default Header

qiita__headerRight-1.png

それでは、スタイリングしていきます。

Header.css
.headerRight{
    display: flex;

}
.headerRight__object{
    display: flex;
    align-items: center;
    margin-right: 20px;
}
.headerRight__object > p{
    color: white;
    font-size: 12px;
    cursor: pointer;
}
.headerRight__object > .MuiSvgIcon-root {
    cursor: pointer;
    color: white !important;
    font-size: 15px !important;
    margin-right: 5px;

}
.headerRight__p:hover{
    text-decoration: underline;
}
.headerRight__p:hover{
    text-decoration: underline;
}

この記事でもちょくちょく出てくる、hoverですが、これは、指定した要素にマウスが乗ったら起こるイベントです。
この場合は、ストック一覧にマウスを乗せるとストック一覧にアンダーラインがかかります。
qiita__headerRight-2.png

あとは、投稿とお知らせ、アバター部分のスタイリングですが、特に新しいことはないので、載せるだけにさせてもらいます。

Hader.css
//投稿する
.headerRight__publish{
    display: flex;
    border: 1px solid #3e9200;
    background-color: #3e9200;
    padding: 5px;
    border-radius: 5px;
    align-items: center;
}
.headerRight__publish > .MuiSvgIcon-root {
    color: white !important;
    font-size: 15px !important;
    margin-right: 5px;
}
.headerRight__publish > p {
    color: white;
    font-size: 12px;
    cursor: pointer;
    margin-right: 3px;
}
.headerRight__publish:hover{
    background-color: #367e00;
}

qiita__headerRight-3.png

Header.css

.headerRight__notification{
    display: flex;
    border: 1px solid #edfce2;
    padding: 3px;
    background-color: #edfce2;
    border-radius: 5px;
    align-items: center;
}

.headerRight__notification > .MuiSvgIcon-root {
    color: #55c500 !important;
    font-size: 20px !important;
    margin-right: 5px;
}
.headerRight__notification > p {
    color: #55c500;
    font-size: 12px;
    cursor: pointer;
    margin-right: 3px;
}

qiita__headerRight-4.png

Header.css
//headerRight Avatar

.headerRight__avatar{
    display: flex;
    align-items: center;
}
.headerRight__avatar > .MuiSvgIcon-root {
    cursor: pointer;
    color: #3a8a00!important;
    font-size: 20px !important;
}
.headerRight__avatar > .MuiSvgIcon-root:hover {
    cursor: pointer;
    color: white!important;
    margin-right: 3px;
}

qiita__headerRight-5.png

さて、なんとか、アバター部分まで、仕上げることができました。
あとはメディアケリーでスタイリングすれば完成です。

Header.css
//mediaQueries

@media screen and (max-width: 757px) {
    .headerRight__object {
        display: none;
    }
    .headerRight__object__media{
        display: flex;
        align-items: center;
        margin-right: 20px;
    }
    .headerRight__object__media > .MuiSvgIcon-root{
        cursor: pointer;
        color: white !important;
        font-size: 15px !important;
        margin-right: 5px;

    }
}

@media screen and (min-width: 758px){
    .headerRight__object__media {
        display: none;
    }
}

完成

モニター大きめ
qiita__navbar-1.png

モニター中くらい
qiita__navbar-2.png

モニター小さめ

qiita__navbar-3.png

お疲れさまでした。

12
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
6