【CSS】:has()セレクタ × WordPress実践的な具体例
はじめに
最近インプットしたCSS擬似クラス:has()の実際に現場で使用した具体例のアウトプットです。
今回の実装を通して改めて:has()の強力さを実感したので、まだhas()を使用していない方はぜひ機会があれば使用してみていただきたい、感動します!
インプットで参考にしたサイトは下記になります。
今回使用した具体的な使用方法
WordPressカスタム投稿・カスタムフィールドで複数の会社情報を管理、Googleマップ(iframe)があるときだけ、gridを超えて横幅いっぱいに広がるデザインの実装。今後も他の会社情報でGoogleマップが追加される想定。
:has()を使用に至った背景
WordPressサイトを構築中、カスタム投稿・カスタムフィールドで複数会社情報を管理する必要があり、
かつその中で本社だけはGoogleマップを掲載し、その他の会社はGoogleマップ無しでレイアウトも変わるという実装をする場面がありました。:has()インプット前の自分なら、おそらくまず新しく管理用のクラスを作るか?という発想になったと思いますが、has()を使用すればカスタムフィールドでiframeのありなしでスタイルの管理ができるんじゃないか?という仮説からドキュメントやブログを読みつつ実際に実装完了に至りました。
完成イメージ
実際のコード
<!-- p-location__container -->
<div class="p-location__container">
<!-- p-location__item Googleマップあり -->
<div class="p-location__item">
<h3 class="p-location__item-title">東京駅</h3>
<address class="p-location__item-info">
<p>住所 : 〒100-0005 東京都千代田区丸の内1丁目</p>
<a href="tel:0000000000">TEL : 000-000-0000</a>
<a href="tel:00000000000">FAX : 000-000-0000</a>
<a href="mailto:info@gmail.com">info@gmail.com</a>
</address>
<!-- カスタム投稿でGoogleマップ情報が入力されているときだけ表示されるようにする -->
<iframe
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3240.828029576439!2d139.7671248!3d35.68123620000001!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x60188bfbd89f700b%3A0x277c49ba34ed38!2z5p2x5Lqs6aeF!5e0!3m2!1sja!2sjp!4v1726018217788!5m2!1sja!2sjp"
title="Googleマップ"
width="600"
height="450"
style="border: 0"
allowfullscreen=""
loading="lazy"
referrerpolicy="no-referrer-when-downgrade"
>
</iframe>
</div>
<!-- Googleマップなし -->
<div class="p-location__item">
<h3 class="p-location__item-title">東京駅</h3>
<address class="p-location__item-info">
<p>住所 : 〒100-0005 東京都千代田区丸の内1丁目</p>
<a href="tel:0000000000">TEL : 000-000-0000</a>
<a href="tel:00000000000">FAX : 000-000-0000</a>
<a href="mailto:info@gmail.com">info@gmail.com</a>
</address>
</div>
.
.
.
</div>
<!-- p-location__container -->
.p-location__container {
/* スタイル調整 */
--padding-inline: 16px;
--max-content-width: 1000px;
padding-block: 60px;
width: min(calc(100% - var(--padding-inline) * 2), var(--max-content-width));
margin-inline: auto;
/* スタイル調整ここまで */
display: grid;
grid-template-columns: 1fr;
}
@media screen and (min-width: 768px) {
.p-location__container {
grid-template-columns: repeat(2, 1fr);
column-gap: 60px;
}
}
.p-location__item {
display: grid;
grid-template-rows: subgrid;
grid-row: span 2;
row-gap: 24px;
align-items: center;
padding-block: 60px;
border-bottom: 1px solid gray;
}
.p-location__item iframe {
width: 100%;
height: auto;
aspect-ratio: 390 / 264;
}
@media screen and (min-width: 768px) {
.p-location__item iframe {
max-width: 390px;
}
}
/* Googleマップ(iframe)があるときだけのスタイル */
.p-location__item:has(iframe) {
grid-template-columns: 1fr;
grid-row: span 3; /* Googleマップ分増えるため */
}
/* pc時にgirdを超えて横幅いっぱいに広がる */
@media screen and (min-width: 768px) {
.p-location__item:has(iframe) {
grid-template-columns: repeat(2, 1fr);
grid-column: 1 / -1; /* 横幅いっぱいに広げる */
align-items: center;
column-gap: 60px;
row-gap: 0; /* p-location__itemのrow-gapを0にする */
}
.p-location__item-title {
grid-column: 1 / 2; /* gridの配置調整 */
}
.p-location__item-info {
grid-column: 1 / 2; /* gridの配置調整 */
}
iframe {
grid-column: 2 / 3; /* 右側に配置する */
grid-row: 1 / 3; /* 2行分の高さを占有する */
}
}
.p-location__item-title {
font-size: 28px;
font-weight: 500;
}
:is(.p-location__item-info) :is(p, a) {
display: block;
line-height: 220%;
}
これで、カスタムフィールドGoogleマップに情報が入力されているときだけ横幅いっぱいに広げるレイアウトが完成しました。これなら新しくクラスを作成して管理するよりもシンプルに、かつ今後他の会社でGoogleマップ情報を追加する時もレイアウトが崩れることはありません。
phpファイルの方では、Googleマップ情報が入力されているときだけ表示、空の場合は表示させないように記述すればOKです。私は普段ACFを使用してカスタムフィールドを管理しているので下記のようになります。
<?php if (get_field('map')) : ?>
<iframe
src="<?php the_field('map'); ?>"
title="Googleマップ"
width="600"
height="450"
style="border: 0"
allowfullscreen=""
loading="lazy"
referrerpolicy="no-referrer-when-downgrade">
</iframe>
<?php endif; ?>
まとめ
今回はCSS擬似クラス:has()の具体的な使用方法についてご紹介しました。日々インプットをしていると、すぐに使う場面がわからなくとも、これどうやって実装しよう?の壁に当たった時の引き出しになるので、軽くでもこういうことができるクラス・プロパティなんだーくらいのレベルで頭に入れておくと、あとは調べたりAIに聞きながら実装できるので、やっぱり日々のインプット習慣は大事なんだなと、実戦を通じて学びました💪
今回の実装を通じて:has()が好きになりました🥰
Discussion