position: sticky要素内のハンバーガーメニューがずれる原因

position: sticky要素内のハンバーガーメニューがずれる原因

当ブログはサイドバーを置かない1カラムのデザインを採用していることもあり、ページ内を移動する手段が記事下部までスクロールしないといけない仕様になっています。

幸い、ヘッダー部分はロゴのみというシンプルなデザインにしているので、そこにハンバーガーメニューを設置しそこから各カテゴリー等へ移動できるようにし、かつヘッダーを追従させるようにすればいいのではと考え追従ヘッダーとハンバーガーメニューを設置したのですが…

なぜかハンバーガーメニューが期待したとおりの位置に表示されず、理想通り表示にするのに少しハマった点を書き連ねてみたいと思います。

目次

wordpressの管理画面にログインしているとずれる

htmlとcssを追記等を行ない、いざ表示させてみるとwordpressの管理画面からログアウトしている状態(ブラウザのシークレットモードでの表示)だと意図した位置にハンバーガーメニューが表示されているのですが、ログインしている状態で管理バー(ツールバー)が出ている状態だとなぜか意図した位置とずれてしまうのです。

左がログイン状態 右がログアウト状態
左がログイン状態 右がログアウト状態

ちなみに表示がずれていた時のhtmlとcssはこちら

<header id="masthead" class="site-header">
	<div class="site-branding">
		<?php
		if ( is_front_page() && is_home() ) :
			?>
			<h1 class="site-title"><?php the_custom_logo(); ?></h1>
			<?php
		else :
			?>
			<p class="site-title"><?php the_custom_logo(); ?></p>
			<?php
		endif;
		?>
	</div>

	<div class="hamburger-menu">
		<input type="checkbox" id="menu-toggle" />
		<label for="menu-toggle" class="menu-btn"><span></span></label>

		<ul class="menu-box">
			<li><a href="#" class="menu-item">cat</a></li>
			<li><a href="#" class="menu-item">tag</a></li>
			<li><a href="#" class="menu-item">home</a></li>
		</ul>
	</div>
</header>
#masthead{
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid rgba(8,19,26,0.15);
  padding: 0 25px;
  position: sticky;
  top: 0;
  background: #ffffff;
  z-index: 1000;
}

.menu-btn{
  position: fixed;
  top: 25px;
  right: 20px;
  width: 26px;
  height: 26px;
  cursor: pointer;
  z-index: 9999;
}

管理バー(ツールバー)が表示されるだけでなぜ位置がずれるのか調べながら色々試行錯誤しているとき、あることに気付きました。

position: fixedとabsoluteの特性に違い

ふとposition: fixedposition: absoluteって何がどう違うのかと疑問に思い調べてみると、この2つには大きな違いがありました。

fixedabsoluteもtop・right・left・bottomで位置を指定してやるのですが、基準となる位置が異なっているのです。

fixedabsolute
ウインドウを基準に絶対位置親要素を基準に相対位置

このような特性の違いがあります。ですので、fixedを使うとウィンドウ基準に位置が決まるので、ログイン状態でページを確認するとハンバーガーメニューが管理バー(ツールバー)に隠れてしまうといった現象が起こってしまうわけです。

では、どのようにすれば解決するかというと…

position: fixedからabsoluteへ変更

解決策は本当に簡単な話で以下のように変更すれば意図した結果を得ることができました。

.menu-btn{
  position: absolute;
  top: 25px;
  right: 20px;
  width: 26px;
  height: 26px;
  cursor: pointer;
  z-index: 9999;
}
左がログイン状態 右がログアウト状態
左がログイン状態 右がログアウト状態

ただ、absoluteを設定する場合、親要素にrelativeabsoluteなどのpositionが設定されている必要があります。

上記のソースコードでは、親要素にposition: sticky;が設定されていますので、fixedからabsoluteへの変更だけでOKでした。

非常に些細なことではあるのですが、プロパティに設定する値の違いで意図した動きや形にならないことがあるということを改めて認識した次第ではあります。

Related posts