1. DX支援サービス

    進化したデジタル技術を浸透させることで人々の生活をより良いものへと変革する

  2. ソフトウェア開発サービス

    VAREALだからできる、RubyとRuby on Railsに特化した、素早く柔軟なソフトウェア開発

  3. AI関連サービス

    データ活用と機械学習を用いたビジネスの着実な深化を。

  4. クリエイティブサービス事業

    美しいだけではない
    機能的UI/UXと正しいコーディング。

  1. 株式会社TOEZ様 幼児向けのレッスン通信講座サイトおよび基幹システムの開発支援

  2. 株式会社カカクコム様 食べログノート の開発支援

  3. 有限会社秀栄社様 パーソナライズ絵本「JibunEHON」の開発支援

  4. 株式会社TRN様 不動産会社・建築会社向け_営業支援システム「renovo」の開発支援

  5. 株式会社Touch&Links様 新規CMSのシステム構築

  6. オフショア開発・長期ラボ型 Webアプリケーション開発事例/顧客ロイヤリティを高めるサービスの開発(株式会社ギフティ様)

  7. イベントサイト 「オンラインで集まろう 学研クリスマス&おとしだまウィーク」

  8. 株式会社ミクシィ様 チケット販売サイトの開発支援

  9. 株式会社ドワンゴ様 e-learningシステム「N予備校」

  10. スカイライト コンサルティング様コーポレイトサイトリニューアル

  11. ハイブリィド株式会社 様 [ IT-Manager SD ]

  12. ライオン株式会社様 パーソナライズされたレコメンドAIの開発

  1. 製造業のDX支援〜営業日報管理システム開発〜

  2. ウォータージェット加工.com サイトリニューアル

  3. 佳秀バイオケムサイトリニューアル

  4. ライオン株式会社様 パーソナライズされたレコメンドAIの開発

  5. 佳秀工業株式会社コーポレートサイトリニューアル

  6. 開発コンサルティング

  7. 団体管理システム

  8. ITコンサルティング

  1. 株式会社カカクコム様 食べログノート の開発支援

  2. 大手建設コンサルティング会社I社様 「自然災害を検知するAI」の開発 

  3. Webサイト訪問者分析のためのデータ分析基盤構築

  4. 製造業のDX支援〜営業日報管理システム開発〜

  5. ライオン株式会社様 パーソナライズされたレコメンドAIの開発

  6. 生産管理システム

  7. 仮想化サーバー導入

  8. タブレット端末導入

  1. 北海道大学様 オープンソースの大規模言語モデル(LLM)を使用したプロダクト共同研究開発

  2. 埼玉医科大学様 画像分類AIを用いた膠原病診断補助ツールの研究開発

  3. 大手建設コンサルティング会社I社様 「自然災害を検知するAI」の開発 

  4. ライオン株式会社様 パーソナライズされたレコメンドAIの開発

  1. イベントサイト 「オンラインで集まろう 学研クリスマス&おとしだまウィーク」

  2. ウォータージェット加工.com サイトリニューアル

  3. 佳秀バイオケムサイトリニューアル

  4. スカイライト コンサルティング様コーポレイトサイトリニューアル

  5. ハイブリィド株式会社 様 [ IT-Manager SD ]

  6. ライオン株式会社様 パーソナライズされたレコメンドAIの開発

  7. 国際的機関の組織内システム開発

  8. 既存会計サービスのUI/UXデザイン改善

  9. 株式会社 クリニカル・トライアル 様 希少疾患SNS「RareS.(レアズ)」

  10. 人材マネジメントシステムUI/UXデザイン

  11. 保育園関連情報メディア開発

  12. Vareal株式会社中途採用情報サイト

Development

擬似セレクタ:has()の活用方法を解説

以前のCSSでは、要素の存在や非存在に基づいて特定の親要素や子要素にスタイルを設定することが困難でした。これまでは、存在する場合と存在しない場合の両方に対応するクラスを作成し、必要に応じてこれらのクラスを切り替えるという手間が発生していました。しかし、約1年前に導入された:has()は、この手間を省き、CSSの作成が以前よりもはるかにシンプルになりました。これにより、要素の存在に応じて親要素や子要素に簡単にスタイルを適用できるようになりました。
今回のブログでは、新たに導入された擬似セレクタ:has()の活用方法を解説いたします。

ブログ作成者紹介

氏名:P・P
所属:開発部
趣味:ボクシング、旅行

擬似クラス:has()とは?

:has()は、:hoverや:focusのような擬似クラスよりも、むしろ:isや:notといった擬似クラスと似た動作をします。:has()を使用するには、親要素に適用される:has()に子要素のセレクタ(またはセレクタのリスト)を渡す必要があります。これは言葉で説明するとわかりにくいので、例を示しましょう。

.header:has(.highlight) {
  margin-bottom: 1rem;
}

このシンプルなセレクタは、.headerというクラスを持つ要素を選択し、その中に.highlightクラスを持つ要素が含まれている場合に、下部に特別なマージンを適用するよう指定しています。これにより、.headerの下部に1remのマージンを設定することができます。

<h1 class="header">
<!-- SELECTED -->
  <span class="highlight"></span>
</h1>
<h1 class="header"></h1>
<!-- NOT SELECTED -->

これは通常のCSSではリスト内の最後の要素のみを選択できるため、実際には逆に思う方もいらっしゃるかと思いますが、:has()要素は他の要素内の要素の存在を確認しながら、実際の親要素を選択できるようにします。

高度な使用法

上記の例では:has()のもっとも単純な使い方を示しましたが、実際にはもっと多くのことができます。

複雑なセレクタの使用

:has()に単一のクラスだけでなく、任意のセレクタを渡すことができます。

.header:has(> .highlight strong#custom-color) {}

これははるかに複雑なセレクタでも正常に動作し、.header要素の直接の子要素に.highlightクラスが含まれ、その中にidがcustom-colorのstrong要素が含まれている.header要素を選択します。

親セレクタだけでなくセレクタ

これまでに話した例では、このセレクタを親セレクタとして使用していますが、実際にはそれ以上のことができます。

.header:has(.highlight) p {}

このセレクタは、.header要素内に.highlight要素が含まれている限り、.header要素内にある任意のpタグを選択します。:has()をセレクタの中間に使用することで、非常に複雑なセレクタを作成し、CSSでは難しいと思われていたことを実現することができます。

複数のセレクタを使用

:has()に複数のセレクタを組み合わせて、非常に複雑な条件を確認できます。

.header:has(.highlight, p) {}
.header:has(.highlight):has(p) {}

上記のコードは似ているように見えますが、実際には異なる条件を確認しています。最初のセレクタは、.header要素またはp要素のいずれかが含まれている.header要素を選択し、2番目のセレクタは.headerとp要素の両方が含まれている.header要素だけを選択します。

特異度

:has()を使用した特異度の計算方法は、通常の擬似クラスと比較してやや複雑です。
:has()と単一のセレクタしかない場合、特異度を計算するのは簡単です。:has()の特異度と外側のセレクタの特異度を単純に組み合わせるだけです。

.header:has(.highlight p) {}

このセレクタは、:has()の外側に1つのクラスがあり、:has()の内側に1つのクラスと1つの要素があるので、セレクタ全体の特異度は2つのクラスと1つの要素です。これは以下のコードと同じ特異度です。

h1.header.red {}

複数の:has()を取り扱う際には、各:has()ごとに特異性が計算され、全体のセレクタの特異度と組み合わされます。

.header:has(.highlight):has(p) {}

このセレクタは、最初の:has()が1つのクラスの特異度を持ち、2番目の:has疑似セレクタが1つの要素の特異度を持っているので、:has()の内側の特異度はすべての:has()の特異度と組み合わされ、外側のセレクタの特異度は1つのクラスであるため、このセレクタ全体の特異度は2つのクラスと1つの要素です。

正規表現との類似

:has()構文を、正規表現における先読みアサーションになぞらえることができる。この類似性は、正のルックアヘッド(?=)と負のルックアヘッド(?!)

肯定先読み

正規表現の領域では、abc(?=xyz)は文字列abcの直後に文字列xyzが続く場合のみ、xyzをマッチに含めずに選択します。:has()と等価なものは.abc:has(+ .xyz)と表現され、次の兄弟.xyzがある場合にのみ.abc要素が選択されることを意味します。:has(+ .xyz)は先読み操作のように動作し、.xyz要素を組み込まずに.abc要素が選択されることを確実にします。

否定先読み

正規表現における負の先読みシナリオ(abc(?!xyz)では、文字列abcの後にxyzが続かない場合にのみマッチします。CSSでは、類似の構文は.abc:has(+ :not(.xyz))で、次の要素が.xyzの場合、.abc要素は選択されないことを示します。

ブラウザサポート

現時点では、:has()はSafari 15.4とChrome/Edge 105で利用可能で、Firefoxではバージョン121でフラグが有効化されています

結論

CSSの進化に伴い、数年間待望していた親セレクタがついに実現しました。おおよそ1年前に導入された:has()は、従来の親セレクタを超えた機能を提供し、開発者にとっては画期的な進歩です。これにより、複雑なCSSスタイルをより効果的に構築でき、親子要素のスタイリングに関する一般的な課題に対処できるようになりました。

この新しいセレクタの導入は、開発プロセスにおいて柔軟性と効率性を向上させ、コードの可読性を高める一助となりました。例示されたように、シンプルな使用法から高度なセレクタの活用まで、:has()は多岐にわたる要件に対応できることが確認されています。

また、正規表現との興味深い類似性も浮かび上がり、開発者はこれまで以上に直感的かつ強力なスタイリングツールを手に入れたと言えます。

現在では、主要なブラウザで:has()が十分にサポートされており、開発者は安心してこの新しい機能を活用できます。CSSの未来に期待が高まる中、新たなセレクタの導入によってスタイリングの新たな次元が切り拓かれました。

おわりに

Vareal株式会社では、わたしたちと一緒に働いていただける方を大募集しています!
興味のある方はぜひ下記リンクをチェックしてみてください!
採用ページ

X(旧Twitter)では社内の雰囲気を発信しています、ぜひフォローしてみてください!
バレアルマン@広報 | ヒーロー【企業公式】

関連記事

%d人のブロガーが「いいね」をつけました。