##はじめに
React記事の一環として、レスポンシブデザインのヘッダーを作成してみます。今回はわかりやすいように、Qiitaと同じヘッダーを作成していきます。
ソースコード:https://github.com/TokyoProgramming/qiita__navbar
- この記事で学べる事
- ReactでのレスポンシブWebデザイン
- MediaQueries
- よくあるヘッダーのデザイン方法
- Material-UI
##1.React構造
- Componentsディレクトリ内
- Header.js
- Header.css
以下のようなシンプルな構造にしています。
##2.Material-UI
それでは今回使用する。Material-UIをインストールしていきます。
npm install @material-ui/core
npm install @material-ui/icons
これで、Material-uiのアイコンを使用できます。
今回使用するMaterial-uiのアイコンたちです。
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と叫ぶことでしょう。
####ヘッダー左側cssスタイリング
まずは、親要素の.headerのスタイリングからです。
.header{
display: flex;
margin-top: 0;
position: sticky;
background-color: #55c500;
width: 100vw;
height: 60px;
justify-content: space-around;
}
なんとも言えませんね。。。
親要素に収まってもいないし。。
どんどんいきます。
.headerLeft {
display: flex;
}
.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;
}
headerLeft__object > .MuiSvgIcon-root
で、Material-UIのアイコンを指定できます。
!important
は、material-uiなどのアイコンはもともとアイコンのスタイルが設定されているため、こちらのスタイルが"重要"であることを伝えるために、記述しなければなりません。
左側から順番に仕上がりつつあります。
//コミュニティ+アイコン
.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で試してみればわかりますが、横幅を小さくしていくと、コミュニティ+アイコンが表示されなくなります。
//検索フォーム
.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
ここまでくるとヘッダーの左側は完成しました。
残り半分頑張っていきます。
##4.ヘッダー右側
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
それでは、スタイリングしていきます。
.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ですが、これは、指定した要素にマウスが乗ったら起こるイベントです。
この場合は、ストック一覧にマウスを乗せるとストック一覧にアンダーラインがかかります。
あとは、投稿とお知らせ、アバター部分のスタイリングですが、特に新しいことはないので、載せるだけにさせてもらいます。
//投稿する
.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;
}
.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;
}
//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;
}
さて、なんとか、アバター部分まで、仕上げることができました。
あとはメディアケリーでスタイリングすれば完成です。
//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;
}
}
##完成
モニター小さめ
お疲れさまでした。