4

それぞれ可変幅の 2 つの要素にボックス シャドウを追加しようとしています。私の望ましい結果は次のようになります。

スクリーンショット

重なっているボックスの影を覆う疑似要素を使用してこの結果を得ようとしましたが、透過性が必要なため、ボックスの端に小さな重なりがない解決策を見つけることができないようです疑似要素も正しい幅に調整されません。私の問題を解決するために、上部のボックスに必ずしも上部の境界線が必要なわけではありません。

フィドル

HTML:

<div>
    <p></p>
</div>
<div>
    <p></p>
</div>

SCSS:

div {
    display: inline-block;
    margin: 75px;
    width: 200px;
    height: 50px;
    position: relative;
    p {
        position: absolute;
        top: 100%;
        left: 0;
        height: 300px;
        width: 250px;
    }
    &, p {
        background: #ededed;
    }
}
div:last-child p {
    width: 150px
}

div {
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2);
    p {
        box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2);
    }    
}

編集:

通常、私はレイアウトに JS を考慮しませんが、私の特定のケースでは、ユーザーの操作が発生するまでボックスが表示されないため、スクリプトを使用して問題を解決しました。スクリプトは、DOM の準備ができたときに上の要素が下の要素よりも大きいかどうかを判断し、それぞれに「大きい」または「小さい」クラスを追加します。それを知ることで、疑似要素の幅がどの要素を継承する必要があるかがわかります。どの要素が大きいかを変更するような方法で要素のサイズが変更されない限り、これはうまく機能します。

また、JS を必要とせず、ボックス サイズのぼかしのみが必要でスプレッドが不要な場合に備えて、疑似要素が 1 つ少ない、よりクリーンなソリューションもあります。

フィドル:

ぼかしと広がりの組み合わせ(JS)

ぼかしのみ、見開きなし(JSなし)

すべての白い背景が黒に置き換えられているこのスクリーンショットでわかるように、最終結果は完全ではありません。

スクリーンショット

左ボックスの左上を見ると、ボーダーの影が少しカーブしているのがわかります。とにかく、それは私に十分に近いです。

cssのみを使用して最初のフィドルと同様の結果をもたらすソリューションを誰かが見つけたら、本当に感謝します。

4

2 に答える 2

2

これには簡単な解決策がありますが、これは実験的な機能であり、サポートが限定されています。

フィルターを使用する: 基本要素にドロップ シャドウを適用すると、ドロップ シャドウがこの要素の複合結果に適用され、すべての子孫に適用されます。

div {
    display: inline-block;
    margin: 75px;
    width: 150px;
    height: 50px;
    position: relative; 
    -webkit-filter: drop-shadow(0px 0px 5px rgba(255, 0,0,0.7));
    filter: drop-shadow(0px 0px 2px red);
}

div p {
    position: absolute;
    top: 100%;
    left: 0;
    height: 300px;
    width: 250px; 
    margin: 0px;
}

div, div p {
    background: #ededed; 
}

#second p {
  width: 100px; 
}
<div>
    <p></p>
</div>
<div id="second">
    <p></p>
</div>

シャドウに疑似要素を使用して、任意のブラウザーで実行される代替アプローチ:

div {
    display: inline-block;
    margin: 75px;
    width: 150px;
    height: 50px;
    position: relative; 
}

div p {
    position: absolute;
    top: 100%;
    left: 0;
    height: 300px;
    width: 250px; 
    margin: 0px;
}

div, div p {
    background: #ededed; 
}

#second p {
  width: 100px; 
}

div:after, p:after {
    content: "";
    position: absolute;
    left: 0px;
    top: 0px;
    right: 0px;
    bottom: 0px;
    box-shadow: 0px 0px 2px 6px rgba(0,255,0,0.7);
    z-index: -10;
}
<div>
    <p></p>
</div>
<div id="second">
    <p></p>
</div>

別の方法は、影を切り取ることです。これはサポートが不十分であり、多くの手動調整が必要ですが、最終結果はおそらく最高の外観になります. Webkit でのみ動作するデモ

div {
    display: inline-block;
    margin: 75px;
    width: 300px;
    height: 50px;
    position: absolute; 
}

div p {
    position: absolute;
    top: 100%;
    left: 0;
    height: 100px;
    width: 200px; 
    margin: 0px;
}

div, div p {
    background: #ededed; 
}


div:after, p:after {
    content: "";
    position: absolute;
    left: 0px;
    top: 0px;
    right: 0px;
    bottom: 0px;
    box-shadow: 0px 0px 15px 15px rgba(255,0,0,0.2);
    z-index: -10;
}

p:after {
    -webkit-clip-path: polygon(0% 30px, 230px 30px, 260px 60px, 100% 100%, 0% 100%);
}

div:after {
    -webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 260px 100%, 230px 80px, 0% 80px);
    
}
<div>
    <p></p>
</div>

于 2015-07-25T07:58:12.220 に答える