WordPressのレイアウト：サイドバー が下にずれる

「WordPress サイドバー 下にずれる」でググると結構出てくる問題。
今回、私の場合をここに紹介するので参考にしてください。

### Prerequisite
制作サイトはCodestepの[WordPressでオリジナルサイトを作ろう](https://code-step.com/wp-menu/)だが、練習のためHTMLとCSSは自分の感性と知識を使って模擬コードを見ずに作った（模擬コードと違いdisplay: gridを使ってレイアウトを作った）。もしかしたらだが、そのためにこの問題が発生したのかもしれない。

### 問題の状況
⑮カテゴリ一覧編や⑯月別一覧編を作成すると、本来、以下のようにメインの表示枠とサイドバーの2列になるところ、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/ba5fda52-c0ae-9cb2-5276-30946cb62e96.png)


サイドバーが下に回り込んでしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/d06eb163-d11f-5078-5a20-bfb31ed3569d.png)

たいてい＜div＞タグの閉じタグが足りないとか余計なものがある、とか、なんだけど、困ったことに「カテゴリ一覧」のどのカテゴリーを選ぶかで結果が違ってくる。例えばCOLUMNカテゴリー一覧を表示させると正常だが、NEWSやHOTELカテゴリー一覧だとサイドバーが下にずれる。

ずれた時の開発者ツールで見えるHTML。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/7cf42c25-1f8a-5a28-a814-3a39d5d19bae.png)

サイドバー＜aside＞タグが＜div id="container"＞の外に出てしまっているが、

正常な場合、ご覧のように、＜div id="container"＞の中にサイドバー＜aside＞タグが格納されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/942ca4fe-65c8-f92d-7453-d560ee7be1c0.png)


### さあ、推理！
こうなる前と後でなにか変更作業はしていないか？
していない。
だって、新規製作中なんだもの。はじめからこの事象が発見された。

正常なカテゴリーと異常なカテゴリー一覧との違いを考えた。
正常なカテゴリー一覧は記事数は多い。異常なカテゴリー一覧はひとつかふたつ。

・・・異常なカテゴリー一覧で記事数を増やしてみよう！

見事に正常にサイドバー表示がされた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/91d42794-a36b-4c28-04e1-2e37918d3735.png)


### 違いはなんだ？

記事数増やしたカテゴリー一覧と記事数が少ないカテゴリー一覧の違いはなんだ？

わかった。ページネーションだ。
管理画面の設定で、1ページ当たりの記事表示数を３にしている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/15b7e3d3-1d60-2b9c-b9f0-6e9a75f30699.png)

つまり、記事数が４つ以上になるとページネーションが現れる。


### 解決方法
ページネーションはプラグインを使わず、function.phpで作成し、カテゴリー一覧ページに埋め込んでいる。

```php
//function.php
// ページネーション
function pagination($pages = '', $range = 2) {
  $showitems = ($range * 2) + 1;

  // 現在のページ数
  global $paged;        // $paged-> WordPressのグローバル変数.現在のページ番号を取得
  if(empty($paged)) {
    $paged = 1;
  }

  // 全ページ数
  if($pages == '') {
    global $wp_query;
    $pages = $wp_query->max_num_pages;      // $wp_query はWordPressのクエリオブジェクトで、
    if(!$pages) {                           // max_num_pagesプロパティはクエリ結果の総ページ数を格納してる.
      $pages = 1;
    }
  }

  // ページ数が2ページ以上の場合のみ、ページネーション表示
  if(1 != $pages) {
    echo '<div class="pagination">';
    echo '<ul>';
    //1ページ目でなければ、「前のページ」リンクを表示
    if($paged > 1) {
      echo '<li class="prev"><a href="' . esc_url(get_pagenum_link($paged - 1)) . '">前のページ</a></li>';
    }
  }

  // ページ番号を表示（現在のページはリンクにしない）
  // 現在のページ番号を中心に前後に $rangeページずつ表示.
  for ($i=1; $i <= $pages; $i++) {
    if (1 != $pages && (!($i >= $paged+$range+1 || $i <= $paged-$range-1) || $pages <= $showitems)) {
      if ($paged ==$i) {
        echo '<li class="active">' . $i . '</li>';
      } else {
        echo '<li><a href="' . esc_url(get_pagenum_link($i)) . '">' .$i. '</a></li>';
      }
    }
  }

  // 最終ページでなければ「次のページ」リンクを表示
  if ($paged < $pages) {
    echo '<li class="next"><a href="' . esc_url(get_pagenum_link($paged + 1)) . '">次のページ</a></li>';
  }
  echo '</ul>';
  echo '</div>';
}
```

```php
// category.php
<?php get_header(); ?>

<div id="container">
        <main class="main">

・・・中略・・・
                <!-- ページネーション埋め込み -->
                <?php
                if (function_exists("pagination")) {
                    pagination($wp_query->max_num_pages);
                }
                ?>
        </main>

    <?php get_sidebar(); ?>
</div>
```


詳細な分析は時間の無駄。ここでは、ページネーションで使っている＜div＞タグを＜section＞タグに変更した。（＜p＞タグにするとページネーションのCSSが当たらなかった）

```php
// ページネーション
function pagination($pages = '', $range = 2) {
  $showitems = ($range * 2) + 1;

  // 現在のページ数
  global $paged;        // $paged-> WordPressのグローバル変数.現在のページ番号を取得
  if(empty($paged)) {
    $paged = 1;
  }

  // 全ページ数
  if($pages == '') {
    global $wp_query;
    $pages = $wp_query->max_num_pages;      // $wp_query はWordPressのクエリオブジェクトで、
    if(!$pages) {                           // max_num_pagesプロパティはクエリ結果の総ページ数を格納してる.
      $pages = 1;
    }
  }

  // ページ数が2ページ以上の場合のみ、ページネーション表示
  if(1 != $pages) {
    echo '<section class="pagination">';
    echo '<ul>';
    //1ページ目でなければ、「前のページ」リンクを表示
    if($paged > 1) {
      echo '<li class="prev"><a href="' . esc_url(get_pagenum_link($paged - 1)) . '">前のページ</a></li>';
    }
  }

  // ページ番号を表示（現在のページはリンクにしない）
  // 現在のページ番号を中心に前後に $rangeページずつ表示.
  for ($i=1; $i <= $pages; $i++) {
    if (1 != $pages && (!($i >= $paged+$range+1 || $i <= $paged-$range-1) || $pages <= $showitems)) {
      if ($paged ==$i) {
        echo '<li class="active">' . $i . '</li>';
      } else {
        echo '<li><a href="' . esc_url(get_pagenum_link($i)) . '">' .$i. '</a></li>';
      }
    }
  }

  // 最終ページでなければ「次のページ」リンクを表示
  if ($paged < $pages) {
    echo '<li class="next"><a href="' . esc_url(get_pagenum_link($paged + 1)) . '">次のページ</a></li>';
  }
  echo '</ul>';
  echo '</section>';
}
```

これで記事数が少ない場合でも、カテゴリー一覧（および月別一覧）でうまくサイドバーが定位置に収まるようになった❣

＼(^o^)／


### WPでは`<div>`タグに注意

構造化要素として＜div＞タグを使うことは良くあるが、WordPressで使ってるとどこからゴミ＜div＞が振って来るかわかりにくい。せっかく`<section>`や`<article>`とか用意してくれるようになったので、WPでは構造化要素としてなるべく`<div>`は使わないようにしようという苦労談でありました。

※ よく`<div class="container">`とか`<div class="wrapper">`とか書いてページ全体を包む要素を作るが、HTML5で＜container＞タグや＜wrapper＞タグを作ってくれるとありがたいな。

<br>
<br>

参考：[Codestep: WordPressでオリジナルサイトを作ろう](https://code-step.com/wp-menu/)
[divは最終手段に使いましょう【セクショニングコンテンツを攻略せよ】](https://qiita.com/samuraibrass/items/3df104681fb0fdbb67ff)