[雑記]CSS:borderの太さをhoverで変更する時のアレコレ

borderの太さをhoverでアニメーションさせる場合に癖が強かったので、色々と試した雑記。

border要素のみ

まずはシンプルにborder要素のみ。

シンプル
<div class="simple">
    シンプル
</div>
.simple {
    display: inline-block;
    border: solid 1px #000;
    padding: 6px;
    transition: 1s;
}

.simple:hover {
    border: solid 3px #000;
}

これだけだとborderのサイズが変わると同時に要素全体のサイズが変わってしまう。
サイズについては縦横比を固定して「box-sizing: border-box;」を設定すれば回避はできる。

シンプル2
<div class="simple2">
    シンプル2
</div>
.simple2 {
    display: inline-block;
    border: solid 1px #000;
    width: 100px;
    height: 50px;
    transition: 1s;
    box-sizing: border-box;
    display: flex;
    justify-content: center;
    align-items: center;
}

.simple2:hover {
    border: solid 3px #000;
}

しかし、要素に合わせたサイズにしたい場合もある。
その場合にはborderで増えた分だけpaddingを減らせば良い。
(以下はborderが2px増えるのでpaddingを2減らした。)

シンプル3
<div class="simple3">
    シンプル3
</div>
.simple3 {
    display: inline-block;
    border: solid 1px #000;
    padding: 6px;
    transition: 1s;
}

.simple3:hover {
    border: solid 3px #000;
    padding: 4px;
}

しかし、ここまでの内容ではアニメーションが滑らかではない。
borderは1pxずつしか変化しないからである。

borderを二重にする

二重でborderを用意し、外側は色を、内側は透明にしておき、hoverで内側に色を付ける。
Paddingなどは内側で設定をするが、外側分のborderを考慮する必要がある。

二重ボーダー
<div class="double">
    <div>二重ボーダー</div>
</div>
.double {
    display: inline-block;
    border: solid 1px #000;
}

.double div {
    border: solid 2px transparent;
    padding: 5px;
    transition: 1s;
}

.double:hover div {
    border: solid 2px #000;
}

動きがフェードになった事で違和感は無くなったが、子要素が増えてしまった。

擬似要素を使う

「position:absolute」を持つ透明な擬似要素を重ねておき、hoverで色を付ける。

擬似要素
<div class="before">
    擬似要素
</div>
.before {
    display: inline-block;
    border: solid 1px #000;
    padding: 6px;
    position: relative;
}

.before::before {
    content: "";
    position: absolute;
    box-sizing: border-box;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    border: solid 2px transparent;
    transition: 1s;
}

.before:hover::before {
    border: solid 2px #000;
}

CSSは少し複雑になったが子要素はなくなった。

擬似要素で枠線に重ねる

ここまでは枠内に太くなったが、擬似要素であれば枠にピッタリ重ねることもできる。
他の要素と被らない様に「margin」などの調整が必要だが、見た目は一番綺麗かもしれない。

擬似要素2
<div class="before2">
    擬似要素2
</div>
.before2 {
    display: inline-block;
    border: solid 1px #000;
    padding: 6px;
    position: relative;
}

.before2::before {
    content: "";
    position: absolute;
    top: -2px;
    left: -2px;
    height: calc(100% - 2px);
    width: calc(100% - 2px);
    border: solid 3px transparent;
    transition: 1s;
}

.before2:hover::before {
    border: solid 3px #000;
}

太さを変更する場合計算をする必要がある。

.before2 {
    display: inline-block;
    border: solid ❶ #000;
    padding: 6px;
    position: relative;
}

.before2::before {
    content: "";
    position: absolute;
    top: -❸;
    left: -❸;
    height: calc(100% - ❹);
    width: calc(100% - ❹);
    border: solid ❷ transparent;
    transition: 1s;
}

.before2:hover::before {
    border: solid ❷ #000;
}

❶は変更前の太さ
❷は変更後の太さ

❶ / 2 + ❷ / 2 = ❸
❷ – ❶ = ❹

.before2 {
    display: inline-block;
    border: solid 2px #000;
    padding: 6px;
    position: relative;
}

.before2::before {
    content: "";
    position: absolute;
    top: -3px;
    left: -3px;
    height: calc(100% - 2px);
    width: calc(100% - 2px);
    border: solid 4px transparent;
    transition: 1s;
}

.before2:hover::before {
    border: solid 4px #000;
}
タイトルとURLをコピーしました