• TOP
  • ブログ
  • プロフィール
  • お問い合わせ
  • ハンバーガーメニュー作ってみた

    ハンバーガーメニュー作ってみた

    よくある3本線のハンバーガーボタンとそれによって開くメニューを、html、css、JSを使って作ってみたやつです。
    codepenにしたためてあったのを今更出す感じなので、実際作ったのは何年も前ですが・・・

    概要

    よくある3本線のボタンで、押すとメニューが画面全体に広がるものを想定しています。

    • クリックするとメニューが開いて、開いている間は閉じるボタン(×)の状態に変わる
    • メニューは縦に並び、画面内の空いたスペースには半透明の黒の背景が入る(その部分をクリックしても閉じる)
    • メニューが画面外に出た場合はスクロールできる

    といった仕様で作っていきます。

    コード解説

    まずは全体像から。

    See the Pen Hamburger by Yoriyasu Nishimura (@yori3) on CodePen.

    ハンバーガーボタン

    ハンバーガーボタンのhtmlは以下の部分です。

    <div class="headerNavToggle"><button class="headerNavToggle__btn"></button></div>

    .c-headerNavToggleのdivがボタン全体の丸い部分、buttonタグがハンバーガーの棒の部分を作っています。

    cssではbuttonタグのbefore、after擬似要素で上下の棒を作り3本線を形成しています(以下)。
    棒の位置を決めるのにtranslateを使ってるのは、後でアニメーションで動かすときに動かしやすいためです。

    〜〜略〜〜
          display: block;
          position: relative;
          width: 30px;
          flex-basis: auto;
          height: 2px;
          background-color: #333;
          &::before,&::after{
            display: block;
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: inherit;
            background-color: #333;
            border-radius: inherit;
            content: "";
          }
          &::before{
            transform: translateY(-10px);
          }
          &::after{
            transform: translateY(10px);
          }
    〜〜略〜〜

    アニメーションはJSでis-open、is-closeクラスを付けたり外したりして操作しています。
    is-close クラスなくても、デフォルトにアニメーション設定したらってお声もあるかもですが、そうするとページ開いたタイミングでもアニメーションが発火してちょっとかっこ悪いのでこうしてます。

    アニメーションでは、上下の棒(before、after擬似要素)の位置と角度を変更することで、×の形になるようにしています。
    やり方はいろいろあると思うんですが、個人的にこのスタイルが色々な形やアニメーションの要望に対応しやすかったので、基本的にはこれで対応してます。

    〜〜略〜〜
          &.is-open{
          .headerNavToggle__btn{
            background-color: transparent;
            &::before{
              background-color: #333;
              transform: translateY(0) rotate(45deg);
              animation: menuBtnTopOpen .5s;
            }
            &::after{
              background-color: #333;
              transform-origin: center center;
              transform: translateY(0) rotate(-45deg);
              animation: menuBtnBottomOpen .5s;
            }
          }
        }
    〜〜中略〜〜
    @keyframes menuBtnTopOpen{
      0%{
        transform: translateY(-10px) rotate(0);
      }
      50%{
        transform: translateY(0) rotate(0);
      }
      100%{
        transform: translateY(0) rotate(45deg);
      }
    }
    〜〜略〜〜

    メニュー本体

    メニュー本体のhtmlは以下の通りです。

    かなりdivの重ねがけになってます。

    <div class="header__nav">
        <div class="headerNav">
          <div class="headerNav__inner">
            <div class="headerNavList">
              <div class="headerNavList__item"><a href="" class="headerNavList__link">Page A</a></div>
              <div class="headerNavList__item"><a href="" class="headerNavList__link">Page B</a></div>
              <div class="headerNavList__item"><a href="" class="headerNavList__link">Page C</a></div>
              <div class="headerNavList__item"><a href="" class="headerNavList__link">Page D</a></div>
              <div class="headerNavList__item"><a href="" class="headerNavList__link">Page E</a></div>
              <div class="headerNavList__item"><a href="" class="headerNavList__link">Page F</a></div>
              <div class="headerNavList__item"><a href="" class="headerNavList__link">Page G</a></div>
              <div class="headerNavList__item"><a href="" class="headerNavList__link">Page H</a></div>
            </div>
          </div>
        </div>
    </div>

    .header__navはヘッダー内でのレイアウト用。今回はpositionで位置決めしています。
    あと、ヘッダー内においては画面幅いっぱい表示で、後ろに黒の半透明を敷くので、その部分もこのクラスで定義しています。

     〜〜略〜〜
       &__nav{
        position: absolute;
        right: 0;
        top: 0;
        width: 100vw;
        height: 100vh;
        padding-top: 100px;/* headerの高さに合わせています */
        pointer-events: none;
        transition: .5s;
        transform: translateY(-100%);
        z-index: 5000;
        &::after{
          display: block;
          position: absolute;
          left: 0;
          top: 0;
          width: 100%;
          height: 100%;
          background-color: rgba(#000,.5);
          z-index: -1;
          opacity: 0;
          content: "";
        }
        &.is-open{
          transform: translateY(0);
          pointer-events: auto;
          &::after{
            transition: .5s;
            transition-delay: .5s;
            opacity: 1;
          }
        }
      }
    〜〜略〜〜

    .headerNavはメニューそのものの大枠になります。
    レイアウトと分けたのは、他の箇所(例えばサイドバーやフッターなど、背景や100%表示はいらないところ)で同じメニューを使いたい場合、このdivタグから中だけを持っていけば、その場所でも使うことができるようにという考えからです。
    なのでこのクラスにかかるスタイルもヘッダー内でしか使わなさそうなheightやoverflowなどは違う部分で適用しています。

    〜〜略〜〜
       &__nav{
    〜〜中略〜〜
        .headerNav{
          max-width: 400px;
          height: 100%;
          margin-left: auto;
          background-color: #f5f5f5;
          pointer-events: auto;
          overflow-y: scroll;
          overflow-x: hidden;
          overscroll-behavior: contain;
        }
      }
    〜〜略〜〜

    .headerNavListとheaderNavList__item、headerNavList__linkはメニューのリストを作るためのクラスとして機能しています。

    〜〜略〜〜
    .headerNavList{
        &__item{
          border-bottom: 1px solid #ccc;
        }
        &__link{
          display: flex;
          align-items: center;
          gap: 1em;
          padding: 1em;
          font-weight: bold;
        }
      }
    〜〜略〜〜

    メニューを開いているときの背景スクロールの停止

    JavaScriptで操作しています。
    メニューを開いたときにbodyタグにposition:fixedを当てることでコンテンツ部分のスクロールを禁止しています。
    それだけだと、開くたびにページトップに戻ってしまうので、scrollpos変数に開く前のスクロール位置の情報を入れることで、閉じたときにその位置に戻れるようになっています。また、その値をbodyタグのtopの値にすることで開いたときにコンテンツの位置がずれて見えないようにしています(bodyタグ内全体がスクロール値分上に上がるので、見かけ上は画面がずれてないように見える)。

    let scrollpos = 0;
    
    //開いたとき
    scrollpos = window.scrollY; //・・・開くときの画面のスクロール位置を取得
    bodyTag.classList.add('is-fixed'); //・・・bodyタグにis-fixedをつける(position:fixed;とかの設定)
    bodyTag.setAttribute('style','top:'+-scrollpos+'px'); //・・・開くときの画面のスクロール位置の負の値をtopに設定
    
    //閉じたとき
    bodyTag.classList.remove('is-fixed'); //・・・is-fixedクラスをとる
    bodyTag.setAttribute('style','top:0'); //・・・topの値を0に戻す
    window.scrollTo( 0 , scrollpos ); //・・・画面のスクロール位置を保存していたスクロール位置に戻す

    まとめ

    よくあるハンバーガーボタンを作ってみました。
    ボタンの組み方だったり、中のメニューの組み方だったり、色々やり方はあると思うんですが、いくつかサイト制作を経験する中で、この組み方が色々なパターンに対応できてそうな感じがしてます。
    必要な要素は押さえられているかと思うので、あとはサイトに合わせてカスタマイズして使えると思います。

    yori3

    2025年1月10日
    【Web】いろいろ試してみた話
  • 超個人的なVK Blocksのおすすめの機能

    超個人的なVK Blocksのおすすめの機能

    この記事は、「Vektor WordPress Solution Advent Calendar 2024」の6日目の記事です。

    VK Blocksとは

    VK Blocksは、Gutenberg のブロックやツールバーを拡張するプラグインです。
    通常では使えないカスタムされたブロックが多数用意されていて便利です。

    僕自身もレスポンシブスペーサーブロック(画面幅に応じて大きさを変えることができるスペーサーブロック)など、よく使っています。

    VK Blocks

    ツールバーにも注目

    しかし、今回注目したいのは、ブロックの方ではありません。

    このプラグインはツールバーの機能も拡張してくれます。
    このツールバーの拡張が、痒い所に手が届く感じでとても助かっています。

    ツールバーとは、ブロックにフォーカスしたときに上(画面内の位置によっては下)に出てくる、ブロックに変更を加える要素が載せられたバーのことです。

    見出しや段落ブロックのツールバーは、デフォルトでは太字や斜体のほか「V(下矢印)」をクリックすると、ハイライトや打ち消し線などが選択でき、ドラッグで選択した範囲にそれらのスタイルを当てることができます。

    デフォルト

    VK Blocks有効化

    No wrapを活用

    このツールバーの中でも個人的には特に「No wrap」という機能がおすすめです。

    「No wrap」を選択すると、選択範囲に「white-space: nowrap」というスタイルが適用された状態になります。
    この状態になると、コンテンツ幅が狭まってテキストが改行していくときに、この範囲の文字は途中で折り返さず、まとまって下の行に落ちてくれるようになります。


    1行目の後ろに空白があるが、選択したところにNo Wrapを適用してるので、そこでまとまって下の行に落ちていることがわかる
    ピンクのマーカー部分にNo Wrapを適用している

    これを利用すると、画面幅によって読みづらいところで改行されることがなくなるので、意図した改行を実装しやすくなります。

    デバイスごとに改行位置を変えたいというようなときには、デバイスごとに改行を入れる機能もあり、そちらを使うのでもできます。ですが、このやり方であれば、ちょうど文章がコンテンツ幅に収まらなくなったポイントで改行してくれるので、複数のデバイスサイズなどを考慮することなく、読みやすい位置での改行をすることができます。

    幅が狭まると、文の途中で折り返してしまう

    途中で改行せず、読みやすいところで改行することができる

    white-space: nowrapってなに?

    一応、「white-space: nowrap」ってどんなcssなのかを書いておこうと思います。

    「white-space: nowrap」とは、指定範囲の途中でテキストが折り返すのを禁止するcssです。(brタグは効く)

    例えばテキストが1文字だけ落ちてしまうときなど、1行に収めて読みやすくすることができます。

    中途半端に1〜2文字落ちてしまう時とか

    無理やり収めることができる

    ※なお、指定した範囲が長すぎると、コンテンツ幅を飛び出してしまうので注意が必要です。

    テキストが折り返さないということはその指定された範囲が一つのまとまりとして扱われるため、その部分が画面内に収まらなくなると下に落ちるしかなくなるということで、文章の折り返し位置を操作することができるというわけです。

    赤字がwhite-space:nowrapを適用している箇所

    まとめ

    • VK BlocksはGutenberg のブロックやツールバーを拡張するプラグインだよ
    • ブロックだけでなくツールバーの機能も拡張してくれるよ
    • ツールバーの「No wrap」という機能を使うと、改行をいい感じにできるよ

    ということで、VK Blocksのお話をさせていただきました。
    まあ、ほぼwhite-spaceの話だったわけですが・・・。

    こういった痒いところに手が届く感じの機能を提供してくれるプラグインはやはり重宝しますね。
    特に改行位置は地味なようで、Webサイトの可読性を考えると重要なポイントで、どこまでこだわるか、どこで妥協するかなど苦心するポイントの一つではあると思うので、それを調整できる機能を提供してもらえるのはとても助かります。

    自分自身、VK Blocksをそこまで使い込んでいるわけでもないので、まだまだ知らない機能があったり、実はとんでもない勘違いをしてる可能性もありますが、そこはいろいろ教えていただけるとうれしいです。

    ブロックやツールバーの拡張は自分でコードを書いて実装することもできますが、こういったプラグインを活用していくことで構築の時間を短縮できたり、制作者や詳しい人の力を借りることもできるので、臨機応変に活用していけるといいのかなと思います。

    yori3

    2024年12月6日
    ツールとか使い方とか
  • 岐阜 WordPress Meetup #76に参加してきた

    岐阜 WordPress Meetup #76に参加してきた

    11月15日に開催された、岐阜 WordPress Meetup #76に参加してきました。
    https://www.meetup.com/ja-JP/gifu-wordpress-meetup/events/304076652

    WordPressのテーマ開発者である、石川さん(『lightning』『X-T9』など)とキタジマタカシさん(『Snow Monkey』、『unitone』など)のお二人が登壇されるとのことで、ぜひお話を聞きたいと思い参加しました。

    登壇① 『プロっぽいページには理由がある ブロックパターン時代のページデザインのコツ』

    1つ目の登壇は、株式会社ベクトルの石川さんによる『プロっぽいページには理由がある ブロックパターン時代のページデザインのコツ』。
    ブロックエディタでサイトを作るときにどうやったらプロっぽいサイトにできるかという視点で、ブロックの取り扱い方のポイントについてお話しいただきました。

    石川さんのあげられたポイントとしては以下の2つでした。

    • 情報のグルーピングを徹底する
    • 情報の重要度を徹底する

    これらのポイントを実現するために注意する点として、余白を挙げられていました。
    ブロックエディタは自由に余白の設定やスペーサーブロックが入れられるため、余白が自由すぎるということがあります。
    そのため設計者以外にルールが伝わってないとトンマナが崩れるという問題が発生します。

    そこで余白のガイドラインを用意しておくことで担当者による違いをなくし、サイト内の統一感のあるデザインをしていこうということでした。

    ベクトルさんの余白のガイドラインはこちら
    https://patterns.vektor-inc.co.jp/margin-guide/

    個人的な考えとしても、Webサイト制作では情報の区切りやまとまりを意識することが大事だと思っていて、この話はかなり腑に落ちました。

    ガイドラインを作るのは時間がかかるところだとは思うのですが、あらかじめ余白など数値のルールを決めておくことで、更新時のデザインのブレがなくなることや、制作時に迷わなくなるというメリットもあると思うので、意識して取り入れたいところです。

    登壇② 『ブロックテーマでサイトをつくってみよう(unitone 編)』

    2つ目の登壇は、キタジマさんによる『ブロックテーマでサイトをつくってみよう(unitone 編)』。
    実際にunitoneをインストールしたWordPress環境を使って、ページを作りつつ、unitoneのオリジナルブロックの解説をお伺いしました。

    詳しくはunitoneのサイトを参照いただくのが良いと思いますが、unitoneは『Every Layout』という書籍で紹介されているレイアウトの考え方を取り入れているそうで、それがWordPressのブロックの相性がいいのではないかという考えのもと設計されているとのことでした。

    実際触ってみたところでも、さまざまなレイアウトを実現するためのブロックが用意されていて、驚いたり、感心したり、一言ではまとめられないほどすごいテーマだと感じました。

    unitoneのブロックの考え方は、『Every Layout』に書かれている考え方をもとに設計されているそうで、自分がWordPressテーマを編集するときや、WordPressを使わない制作の場面でも取り入れるとよさそうな考え方がたくさんあるなと思いました。

    感想

    テーマ制作者のお二人のお話は、どちらも余白やレイアウトというcssの設計の部分に関するところだったのですが、自分自身もcssを書くので、思い当たるところもたくさんあり、WordPressやテーマと関係がないところのWeb制作という意味でもとても参考になったと感じています。

    実際、自分自身はあまり既存テーマを利用してサイト制作をするということはしていないため、テーマそのものにお世話になることは少ないのですが、それぞれのブロックにどういうcssが当たっているかなどをみることはよくあるので、今回、どういった考え方で設計されているかということを聞けたのはとても良かったです。

    テーマとして良いものであることはもちろんですが、Web制作者としてはどのようにテーマが作られているのかを見るのも勉強になると思いました。

    yori3

    2024年11月17日
    【Web】いろいろ試してみた話
  • 【WordPress】ブロックエディタで画面端まで広がる画像とテキストのカラムレイアウトの作り方

    【WordPress】ブロックエディタで画面端まで広がる画像とテキストのカラムレイアウトの作り方

    下のような画像とテキストの2カラムのコンテンツで、画像が画面端まで、テキストは固定幅(もしくはコンテンツインナーの幅)になっているようなレイアウトをブロック再現してみようと思います。

    こういうやつです(参考:https://www.enpay.co.jp/service/top)

    実装方法

    ①カラムブロックを 50/50 で配置し、画像とテキストをそれぞれのカラムに入力します

    ②テキストはグループブロックでラップしておきます。

    ③カラムブロックの幅を「全幅」にします。

    ④テキストをラップしたグループブロックにテキストの最大幅を設定し、配置を左寄せにします。

    ⑤カラムブロックの横方向のブロックの間隔を「なし」(0)にします。

    ⑥テキストをラップしたグループブロックの水平方向のパディングを設定します。(コンテンツ幅と揃うようにするときれいかも)

    以上の操作をすることで、以下のようなレイアウトが完成です。(上記の手順はどの順番で操作しても問題ありません)

    ⑤〜⑥でカラムブロックの間隔を0にして、テキストのグループにパディングを設定しているのは、モバイルで縦積みになったときに画面端にテキストがくっついてしまうのを防止するためです。

    まとめ

    以前、案件で対応したときにがっつりCSSを書いて対応したのですが、今ならブロックだけでできるのでは?と思いついてやってみました。
    コーポレートサイトなどでよく見かけるレイアウトなので使い道はありそうかなと思います。

    余白や間隔の値や付け方はテーマによって異なるので、同じようにできないテーマもあることは注意が必要です。
    (この記事での手順の画面はTwenty Twenty-Fourのものを使用しています)

    yori3

    2024年11月10日
    【Web】いろいろ試してみた話
  • サイトデザインのリニューアル

    サイトデザインのリニューアル

    サイトデザインをリニューアルしました。

    前のデザインはもう5年くらい前に作ったもので、随分とそのままにしていたんですが、WordPressのブロックエディタもかなりバージョンアップして機能が増えてきたので、それに合わせる形で組み直そうと思ったのが始まりです。

    その上で、せっかくなので見た目の部分でも少し手を加えようと考えました。

    機能的な変更

    サイト全体をWordPressのブロックエディタの機能をメインにして構築するようにしました。
    基本的にはブロックでパーツを構成し、スタイルを選択し、それでも足りないところをCSSで追記するという形をとっています。

    理由としては、このサイトをブロックの機能を試す場としても使いたいと考えているということと、このサイトはブログを主として運用していくことを想定しているため、ブロックエディタを使う方が捗るだろうと考えたからです。

    今後ブログで色々なブロックの組み合わせを紹介できればと思っています。

    見た目の変更

    キーカラーの変更

    #61a6c6 → #00AFCC

    前はくすんだ青色のような色を使っていたのですが、もう少し明るさが欲しかったので、今回はターコイズブルーを採用しました。
    ターコイズブルーは緑みのある青色で、青の落ち着いた雰囲気と、緑の爽やかさ、活発さが合わさったイメージで、自分の目指す、落ち着きがあり、人当たりの良い人物像にぴったりだと思いました。

    ロゴデザイン

    ロゴデザインも少し変更しました。
    ロゴはPoppinsというフォントをベースに角を丸くして、柔らかい雰囲気が出るよう調整しました。人当たりよく、柔らかく人接したいという思いを込めています。
    また、iの点の部分を虫眼鏡に置き換えていますが、これは、興味を持ったことはとことん知りたいという自分の性格と、周りをよく観察して必要な行動を考えるという仕事への姿勢を表しています。

    まとめ

    ブロック中心での構築は、仕事ではやっていたのでそこまで抵抗はなかったですが、一つ一つのブロックの使用を理解して作成する必要があるので、そこはやはり苦労した点です。
    慣れてくると、ブロックでいろいろ表現できることが楽しくなってくるので、クライアントワークで納品するときにもそういった面白さみたいなものも一緒に伝えられたらいいなと思いました。

    せっかくサイトリニューアルしたので、今後はしっかりブログもやっていこうと思っています。

    今までクオリティやら内容やらで「これで出して良いのか」と悩みつつ、ほったらかしにしてた下書きたちをとりあえず生焼けの状態でも出していこうかなと。

    とりあえずCSSやWordPressのブロックエディタの下書きが溜まってるので、放出していきたいと思います。

    yori3

    2024年11月5日
    【Web】いろいろ試してみた話
  • 【CSS】フォトフレーム風のボックスを作る

    【CSS】フォトフレーム風のボックスを作る

    CSSで、写真の角を差し込んだフォトフレームのような見た目を再現してみようと思います。

    実装

    See the Pen Photo frame by Yoriyasu Nishimura (@yori3) on CodePen.

    解説

    htmlは外側の枠であるframeというクラス名のdivタグとその内側に画像を入れるboxというクラス名のdivタグで構成されています。

    boxクラスの擬似要素で白背景で1辺だけborderをつけた正方形を作り、それぞれ斜めに回転させて、画像にやや重なるように右上と左下に配置しています。それにより写真が切り込みに差し込んで固定されているような表現になります。

    ポイントとしては切り込み(擬似要素の辺)の長さが画像から少しだけはみ出るようにすることで、リアリティが出るかと思います。

    まとめ

    以前、いろいろサイトを見てたときに見つけたものを自分で再現してみました。

    ギャラリー的な要素などで利用できそうな小技なので、覚えておいて損はなさそうです。

    yori3

    2024年10月23日
    【Web】いろいろ試してみた話
前のページ
1 2 3 4 … 11
次のページ

©️ 2024 yori3 All rights reserved.