liタグをCSSだけで順番を変える

スタイルシートの進化はほんとにすごいものがあります。
10年前はできなかったことが、今では容易にできます。

スタイルシートは、ブラウザの機能に依存しているため、ブラウザが日々バージョンアップしていることで進化してきました。

今回CMSのページ送りで、昔はabsolute等を使用して無理やりレイアウトしていたものを、もっとスマートにできないかと思い調べたところ、absoluteを使わずに、スタイルシートだけで実現できました。

備忘録として記録いたします。

今回やりたいこと

CMS用のページ送り部分を、スマホ表示の時に表示レイアウトを変えたいと思いました。
具体的には以下の通りです。

これをスマホの時に以下のようにしたいと考えました。

簡単にできそうでできない部分

一見簡単にできそうな感じもしますが、そうでもありません。

まずサンプルのHTMLは以下の通りです。

<ul>
    <li>←</li>
    <li>↑</li>
    <li>→</li>
</ul>

↑矢印を、2番目のliタグに記載しています。
PC表示の時に、中央に表示するため2番目のliタグに配置します。

ここまでは簡単なんです。
順番に表示するだけなので、gridやflexで順並びで実現できます。

問題なのはスマホ表示です。

2番目のliタグを一番上に表示するためには、liタグが1番目になくてはできません。
つまり、liタグの順番を1番目と2番目を入れ替える必要があるのです。

これが思いのほか難問でした。

absoluteの場合は、無理やりできるけど欠点もある

absoluteを使用すれば、2番目のliタグを無理やり1番上に表示できます。
ですが以下の欠点があります。

  • 寸法をきっちり揃えないとずれる

どういうことかというと、absoluteは高さを持たないため、余白やマージンを精密に設定しないとレイアウトがずれます。

例えば文字数が増えて2行にまたがる場合、簡単にレイアウトが崩れます。
固定文字数ならば、何とかなりますが、汎用性に低いです。

最近知りましたが、順番を入れ替えするスタイルシートがある

2番目のliタグを1番目に配置すれば、事は簡単です。
flexを使い、改行OKとし1個目を横幅100%、2個目、3個目を50%にすればよいだけです。

ですが、どうやればいいのでしょうか?
調べてみると以下のようなことがわかりました。

  • display:flexには、順番を入れ替える命令がある

具体的には以下のような記述です。

ul
{
    display: flex;
    flex-wrap: wrap;
}    

ul li:nth-of-type(2)
{
    order: -1;
}

このように記述すると、1個目のliタグと2個目のliタグが入れ替わります。
ちなみに以下のような記述でもOKです。

ul
{
    display: flex;
    flex-wrap: wrap;
}    
ul li:nth-of-type(1)
{
    order: 2;
}
ul li:nth-of-type(2)
{
    order: 1;
}
ul li:nth-of-type(3)
{
    order: 3;
}

-1を指定すると、前の要素を入れ替わります。
ダイレクトに、順番を指定することもできます。
用途に合わせて指定すればよいのです。

ただしこの指定はflexでしか使えない

とても便利な指定ですが、注意点として親要素がdisplay:flexの時しか有効になりません。
display:blockでは、うまく動作しませんでした。

ちなみに、display:gridでは動作しました。

レイアウト配置系のスタイルシートで動作するようです。

デフォルト状態で、要素の順番入れ替えができれば、汎用性が非常に高いと思いましたが、そこは制限があるようです。

ですが、これでやりたいことができました。
2番目のliタグをスマホ表示の場合は1番目に配置してレイアウトでいました。

今回のソースはこちら

今回のソースはこちらです。
スマホの時は順番を入れ替えて、1番上に配置しています。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="Shift-JIS">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>順番を入れ替える</title>
<style>
body
{
    text-align: center;
    padding-top: 100px;
}

ul
{
    display: inline-flex;
    column-gap: 10px;
    text-align: center;
    padding: 0px;
    margin: 0px;
}

ul li
{
    list-style: none;
    padding: 0px;
    margin: 0px;
    display: inline-block;
    padding: 10px;
    box-sizing: border-box;
    min-width: 200px;
    color: #fff;
    background-color: #aaa;
}

ul li:nth-of-type(2)
{
    color: #aaa;
    background-color: transparent;
    border: solid 1px #aaa;
}

@media screen and (max-width: 599px)
{
    ul
    {
        display: flex;
        flex-wrap: wrap;
    }

    ul li
    {
        min-width: initial;
    }

    ul li:nth-of-type(2)
    {
        order: -1;
        width: 100%;
        display: block;
        flex-shrink: 0;
        margin-bottom: 10px;
    }

    ul li:nth-of-type(1),
    ul li:nth-of-type(3)
    {
        width: 48%;
    }

    ul li:nth-of-type(3)
    {
        margin-left: auto;
    }
}
</style>
</head>
<body>
<ul>
    <li>←</li>
    <li>↑</li>
    <li>→</li>
</ul>
</body>
</html>

「これできないかな?」は意外とできることが多い。

HTMLコーディングは、自分の知識で構築します。
そのため、自分の知らない方法は使用できません。

しかも、自分の知識の範囲内で解決できれば、新しい知識を知る必要がありません。
これが、知識のガラパゴス化になります。

今回、自分の知っている方法で解決できましたが、もっと良い方法がないか調べたところ見つけることができました。

知識に貪欲になることが大事なのだと痛感する事例でした。

今回のレポートは以上です。
読んでいただいてありがとうございました。


ホームページに関するお悩み事やご相談事がございましたら私どもまでご連絡ください。 鋭意ご対応申し上げます。
ホームページのご提案もさせていただいております