🎆

CMS用のHTMLテンプレートコーディングのtips

2024/05/18に公開

cms更新が入るページ では、LPや静的ページに比べ、考慮することが多々あります。
コーディングをお願いする人への確認用としてその辺のtipsをまとめました。
毎回、個別にお願いするより記事にした方が早いなと。

こんなケースをカバーしましょう、という記事です。

  • 想定されたテキスト量より大幅に多かった
  • デザインより要素が少なかった
  • 間違ったサイズの画像が登録された
  • エラーの時の対応
  • CMS化出来ないマークアップ

なお本記事のhtmlとcssはほとんど、AI Code Editorの「Cursor」に書いてもらいました。
VSCodeを使ってる方なら、インターフェースはほぼ同じなので、移行もすんなり行けてお勧めです。
https://cursor.sh/

画像編

デザインと違い、サムネが登録されない可能性がある

newsページや商品ページで、画像が登録されないパターンもあります。
「必ず登録してください!」という運用にするのもアリだと思いますが、
更新担当者も素材を調達出来ない場合もあるので、
「代用画像を用意して表示する」 or 「画像が無い場合のレイアウトを表示する」
という対応をとりましょう。

間違った比率の画像がアップロードされる

例えば、「16:9」で想定されたサムネイルリストで、
間違った比率の画像がアップロードされる可能性もあります。
以下のサイズだと微妙にズレてよろしくない見栄えになります。

html
<div class="wrap">
  <div class="item">
    <img src="https://placehold.jp/3d4070/ffffff/640x360.png" alt="" />
  </div>
  <div class="item">
    <img src="https://placehold.jp/3d4070/ffffff/640x364.png" alt="" />
  </div>
  <div class="item">
    <img src="https://placehold.jp/3d4070/ffffff/640x350.png" alt="" />
  </div>
</div>
css
.wrap {
  display: flex;
  gap: 5px;
}
.item {
  width: 200px;
  img {
    width: 100%;
    height: auto;
  }
}

wordpressのプラグインで、これらのサイズを縛る、という運用でもいいのですが、
それよりは規格外の画像でも16:9で表示出来るように実装してあげた方が優しいと思います。

html
<div class="wrap">
  <div class="item">
    <img src="https://placehold.jp/3d4070/ffffff/640x360.png" alt="" />
  </div>
  <div class="item">
    <img src="https://placehold.jp/3d4070/ffffff/640x364.png" alt="" />
  </div>
  <div class="item">
    <img src="https://placehold.jp/3d4070/ffffff/640x350.png" alt="" />
  </div>
</div>
css
.wrap {
  display: flex;
  gap: 5px;
}
.item {
  width: 200px;
  aspect-ratio: 16 / 9;
  img {
    width: 100%;
    height: 100% !important;
    object-fit: cover;
    height: auto;
  }
}

CMS管理の画像を、cssファイルには書かない。

cssファイルに書かれると、cms側で更新することが出来ません。

css
.p-photo {
    background-image: url('background.jpg');
}

これなら更新出来ます!

html
<div class="p-photo" style="background-image: url('background.jpg');"></div>

画像がリンク切れになる

登録はしているが色々な要因で画像が表示されない、というケースもあります。
その時は、崩れ防止のため以下のようなjsを埋め込んでおくと最低限の見栄えは担保されます。

html
<img 
 loading="lazy"
 src="/wp/wp-content/uploads/hoge.png"
 onerror="this.src='/wp/wp-content/themes/test/assets/images/common/no-photo.jpg'"
 alt=""
 >

PCとSPの画像の出しわけにはpicureタグを使用する

PC画像の解像度がデカい場合は、SP用の軽い容量の画像も出力するようにCMS側で調整して、
それぞれ別々で読み込めるようにする。
display:none;での切り替えは実際に不必要な画像まで読み込まれてしまうのでやめましょう。

html
<picture>
  <source srcset="image-desktop.jpg" media="(min-width: 1024px)">
  <source srcset="image-mobile.jpg" media="not all and (min-width: 1024px)">
  <img src="image-desktop.jpg" alt="Description">
</picture>

参考
https://zenn.dev/tak_dcxi/articles/690caf6e9c4e26#モバイルファースト(min-width)で書く

flexbox編

要素の数によってはおかしい表示になる

Flexboxのjustify-contentで、
数によって、おかしい表示になる場合があるので、どの数がきても正常に表示されるようにしておきましょう

こちらの記事が参考になります。
https://blog.webcreativepark.net/2016/08/15-125202.html
https://codepen.io/to-r/pen/bezjrQ

詳細ページ編

Wiziwigエディターエリアなのにタグにclassがついている

Wiziwigエディタ内は基本、classをつけない方がいいです。
方法がないわけではないですが、CMS側からclassをつけるのが困難だからです。

<div class="article-body">
   <!-- ここから本文 -->
  <p class="article-photo">あああ</p>
  <p class="article-image">
    <img src="dummy">
  </p>
    <iframe src="dummy" class="article-frame"></iframe>
    <!--/ ここまで本文 -->
</div>

こんな感じにして、

<div class="article-body">
    <!-- ここから本文 -->
  <p>あああ</p>
  <p><img src="dummy"></p>
    <iframe src="dummy"></iframe>
    <!--/ ここまで本文 -->
</div>

このようにstyleを当てた方無難です。今はcssで入れ子に出来るいい時代。

.article-body {
  /* 段落のスタイル */
  p {
    margin-bottom: 16px; /* 下マージン */
  }
  p:has(img) {
    padding: 10px; /* 画像を含む段落のパディング */
    background-color: #f0f0f0; /* 背景色 */
  }
  p:has(iframe) {
    padding: 10px; /* 画像を含む段落のパディング */
  }
  p:last-child {
    margin-bottom: 0; /* 最後の段落の下マージンをなしに */
  }
  /* iframeのスタイル */
  iframe {
    width: 100%; /* 幅を100%に */
    border: none; /* ボーダーなし */
    aspect-ratio: 16 / 9; /* アスペクト比 */
  }

  /* 最後の子要素のスタイル */
  > *:last-child {
    margin-bottom: 0; /* 最後の子要素の下マージンをなしに */
  }

  /* 見出し2のスタイル */
  h2 {
    font-size: 24px; /* フォントサイズ */
    color: #333; /* 色 */
  }
  h2:first-of-type {
    margin-top: 0; /* 最初のh2の上マージンをなしに */
  }

  /* リストのスタイル */
  ul li {
    list-style-type: disc; /* リストスタイルタイプ */
  }
  ul li:only-child {
    list-style-type: none; /* 子が1つだけの場合はリストスタイルなし */
  }

  /* 外部リンクのスタイル */
  a[href^="http://"], a[href^="https://"] {
    color: #1a0dab;
    text-decoration: underline;
  }

  /* 順序付きリストのスタイル */
  ol {
    padding-left: 20px;
    list-style-type: decimal;
  }
  ol > li {
    margin-bottom: 10px;
  }

  /* 定義リストのスタイル */
  dl {
    padding: 10px;
    background-color: #f4f4f4;
  }
  dt {
    font-weight: bold;
  }
  dd {
    margin-left: 20px;
    color: #333;
  }
}

:has セレクターもモダンブラウザで使用出来るので、classをつけなくても
対応出来るパターンがほどんどだと思います。
https://developer.mozilla.org/ja/docs/Web/CSS/:has

aタグなどのurlが画面からはみ出している。

スマフォサイトでよく見るやつ、もったいない、、と思ってしまう。
ラッパーに以下を追加して、折り返し設定を忘れずにしましょう。

.article-body{
  word-break: break-all;
}

ページャー編

スマフォの小さい画面で、ページャが潰れる

こちらの記事のように、スマフォではPCのように全要素を表示させるのが厳しいので、
不要なものは削るなりして、潰れないように配慮が必要です。

よく、「PCとSPで表示件数を分けたい」と言われるのですが、SPAならまだしも
MPAサイトではかなり難しいと思います。

https://nakox.jp/web/wordpress/wp_pager_css#outline__3_6

スマフォ表示時はいらないやつけずっちゃいましょう!

こちらの記事でも言われているように、ページャーで不要な要素を削って調整した方がいいですね。

長すぎるテキストが入力される

テキストが長い時に、ぱんくずが崩れる

スマフォサイズでは、結構潰れがちではないでしょうか?

html
<nav aria-label="Breadcrumb">
  <ol class="breadcrumb">
    <li class="breadcrumb-item"><a href="#">ホーム</a></li>
    <li class="breadcrumb-item"><a href="#">カテゴリ</a></li>
    <li class="breadcrumb-item active" aria-current="page">サブカテゴリ</li>
  </ol>
</nav>
css
.breadcrumb {
  display:flex;
  list-style: none;
  padding: 8px 12px;
  background: #f8f9fa;
}

.breadcrumb-item {
  font-size: 14px;
}

.breadcrumb-item a {
  color: #007bff;
  text-decoration: none;
}

.breadcrumb-item::after {
  content: ">";
  padding: 0 8px;
}

.breadcrumb-item:last-child::after {
  content: none;
}

.breadcrumb-item.active a {
  color: #6c757d;
}

なので、3点リーダーを出して省略するようにしましょう。

css
/* これを追加 */
.breadcrumb-item.active{
  overflow: hidden;
  display: -webkit-box;
  text-overflow: ellipsis;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  max-width: 130px;
}

一覧のカードのタイトルが長すぎる

こういう要素もタイトルが長い時、一覧のテキストはある程度で切ってしまった方が、スッキリすると思います。(詳細はクリックしてね、ということで、、)

html
<div class="card">
  <img src="https://placehold.jp/3d4070/ffffff/300x200.png" alt="サムネイル" class="card-img">
  <div class="card-body">
    <h4 class="card-title">カードのタイトルカードのタイトルカードのタイトルカードのタイトルカードのタイトルカードのタイトルカードのタイトルカードのタイトル</h4>
    <a href="https://example.com" class="card-link">詳細を見る</a>
  </div>
</div>
css
.card {
  width: 300px;
  border: 1px solid #ccc;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
  transition: box-shadow 0.3s ease-in-out;
}

.card:hover {
  box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}

.card-img {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

.card-body {
  padding: 15px;
}

.card-title {
  margin: 0;
  margin-bottom: 10px;
  font-size: 18px;
}

.card-link {
  text-decoration: none;
  color: #007BFF;
  font-weight: bold;
}

cssだけで、2行に出来ました!
これだとPC→3行、SP→2行のように分けて表示することも可能です。

css

.card-title {
  margin: 0;
  margin-bottom: 10px;
  font-size: 18px;
  /* ここを追加 */
  line-height: 1.2; /* 行間の高さを設定 */
  height: 2.4em; /* 行間の高さの2倍(2行分) */
  overflow: hidden; /* 余分なテキストを隠す */
  text-overflow: ellipsis; /* 切り捨て部分に省略記号を表示 */
  display: -webkit-box;
  -webkit-line-clamp: 2; /* 表示する行数を2行に制限 */
  -webkit-box-orient: vertical;
}

ボタンのテキスト量は読めない

cmsは関係ないかもですが、ボタンのような汎用パーツは、
色んなテキスト量に対応出来るように作りましょう。

html
<p><button class="c-button"><span>ボタン</span></button></p>
<p><button class="c-button"><span>長い長い長いテキストのボタンです</span></button></p>
<p><button class="c-button"><span>2行もあります<br>2行です</span></button></p>
css
.c-button {
  background-color: #4CAF50;
  border: none;
  color: white;
  padding: 0 35px 0 16px;
  text-align: center;
  text-decoration: none;
  display: block;
  font-size: 14px;
  margin: 4px auto 4px 0;
  cursor: pointer;
  border-radius: 8px;
  height: 60px;
  min-width: 300px;
  position: relative;
  box-sizing: border-box;
  line-height: 1.3;
}
.c-button span {
  text-align: left;
  display: inline-block;
}
.c-button::after {
  content: '→';
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
}

最後に

この記事で書いたものは非機能要件 のものが多く、誰かが指示してくれるものではありません。
ここまでカバー出来る人は案外少なかったり。。

https://products.sint.co.jp/ober/blog/nonfunctionalrequirements

目立ちにくいですが、上記がきちんとカバー出来る方は価値が高いコードが生み出せる人材だと思いますし、個人的にもぜひお近づきになりたいので、この記事が良いと思ったら、フォローお願いします!!

Discussion