[css]特定の子要素を持つ要素を指定する:has()

欲しかったはずなのに無くても平気になっちゃった。

こういうこと

    <div class="parent">
        <div class="child01">あああ</div>
    </div>
    <div class="parent">
        <div class="child02">あああ</div>
    </div>
.parent:has(.child01){
    color: red;
}

.child01を持つ.parentのみが装飾される、という内容。

個人的活用シーン

<label class="title">checkbox</label>
<label><input type="checkbox"><span>あああああ</span></label>

<label class="title">radio</label>
<label><input type="radio"><span>あああああ</span></label>
label{
    &.title{
        /* 見出し */
    }
    &:has(input[type="checkbox"]){
        /* checkboxの入ってるlabel */
    }
    &:has(input[type="radio"]){
        /* radioの入ってるlabel */
    }
}

フォームを作る際、<label>は見出しとして使用される。

例外として、checkboxとradioは<label>で囲ったらinput部分以外もクリック領域にできるので、そういう使い方もある。

:has()を使ったらcheckbox、radioをラッピングしてる<label>をピックアップできるよねという。

でもまあclassを付けたり、直接<label>を指定しなくても親要素込みで割り振ってもいいじゃんって話でもあるので、使わなくても困らないというのが現実。

0からの構築じゃあんまり用途がない。
後付で装飾する場合に、htmlをいじれないなら使おうか、ってくらいか。

あんなに欲しかったのにな。

要らないな。

用途あった

忘れてた。

<div class="sample">
    <select>
        <option>...</option>
    </select>
</div>
.sample:has(> select){
    appearance: none;
    position: relative;
    border: 1px solid #ddd;
    background: #fff;
    &::before{
        content: "↓";
        color: #fff;
        font-size: 14px;
        text-align: center;
        line-height: 20px;
        width: 20px;
        height: 20px;
        background: red;
        border-radius: 50%;
        display: block;
        position: absolute;
        top: calc(50% - 10px);
        right: 10px;
    }
    select{
        position: relative;
        z-index: 1;
        background: none;
        border: none;
    }
}

<select>直前の親要素を指定できるから、<select>の装飾が圧倒的に楽になった。

<select>を装飾するためにappearance: none;を付けると矢印が消える。
<select>自体に矢印をつける手段はない。
<select>は疑似要素が使えないから詰んでる。

矢印を設置したいなら別の要素から引っ張る必要があって、一番手っ取り早いのは<select>の親要素周りからなんだけど、手打ちでhtmlを作るなら良いんだけどContactForm7とかで出力したときには勝手に色々DOM要素が付随したりする。
そうなるとその要素を使ったほうが手っ取り早いし、なんならそれらにstyleが予め設定されてたりして、その調整のことも考えたら尚の事<select>の親要素を指定する手段が有り難かったりする。

実用性を考えて、例えばこんな感じ。

$(function(){
    $('select').wrap('<div class="select_wrap">');
})
.select_wrap:has(> select){}

js(jQuery)でラッピングして、そのセットをスタイルのセレクタにすれば他に干渉するリスクも軽減しそうでいいよねってかんじ。

まあこれを採用すると元々この例のように直前・直後で指定してる装飾なりギミックがあったら崩壊するので、新たなリスクが発生する。

どうですか。

コメント

タイトルとURLをコピーしました