LoginSignup
5
5

More than 3 years have passed since last update.

transform: scale()で縮めた要素をposition: absoluteで絶対位置表示した時に、想定位置に表示されない問題を調べた

Posted at

経緯

8pxの文字を表示したいという意志
chrome君の絶対10px以下の文字は許さないという仕様

うーん、そんな時には10pxの文字を0.8倍表示!

デザインの指定では、ブロックの右下の端に表示ってあるから絶対位置指定で・・・

html
<body>
<div class="container">
  <div class="badge">
    8px
  </div>
</div>
</body>
css
.container {
    background: skyblue;
    height: 100px;
    width: 100px;
    position:relative;
}

.badge {
    background: green;
    color: white;
    height: 15px;
    width: 15px;
    font-size: 10px;
    transform: scale(0.8);

    position: absolute;
    bottom: 0;
    right: 0;
}

スクリーンショット 2019-11-23 22.04.11.png

え、なん?隙間なんなん?

原因究明

原因を特定するため、

  • 絶対位置指定をいったん止める
  • コンテナサイズを縮小前バッヂのサイズと同じにする

でどうなるか見てみます。

css(変更後)
.container {
    background: skyblue;
    height: 15px;
    width: 15px;
}

.badge {
    background: green;
    color: white;
    height: 15px;
    width: 15px;
    font-size: 10px;
    transform: scale(0.8);
}

すると・・・

スクリーンショット 2019-11-23 22.29.12.png

こうなりました。

ここから、transform: scale()で縮小・拡大する際は、中心を基準にして指定倍のサイズになるということがわかりました。

バッヂサイズを0.8倍して、(元サイズ - 縮小後サイズ) / 2の1.5px分のマージン(に似て非なるもの)が、上下左右についた状態で表示される感じ

解法1 transformでの変化の基準点を指定する

transform-origin: right bottom;と指定することで、右下基準で変化させることができる。

css
.container {
    height: 100px;
    width: 100px;
    background: skyblue;
    position: relative;
}

.badge {
    padding: 0;
    background: green;
    color: white;
    height: 15px;
    width: 15px;
    font-size: 10px;
    transform: scale(0.8);
    transform-origin: right bottom;

    position: absolute;
    bottom: 0;
    right: 0;
}

スクリーンショット 2019-11-23 23.48.54.png
想定どおりに表示された!

解法2 絶対位置指定をマイナスで指定する

transform-originがどーしても使えない状況があった場合(なさそう)、(元サイズ - 縮小後サイズ) / 2分だけマイナス絶対位置を指定することで無理やり右端に合わせることができる
が、
-1.5pxなど、少数が絡むとうまくいかないので注意!

うまくいかないパターン

css
.container {
    height: 100px;
    width: 100px;
    background: skyblue;
    position: relative;
}

.badge {
    padding: 0;
    background: green;
    color: white;
    height: 15px;
    width: 15px;
    font-size: 10px;
    transform: scale(0.8);

    position: absolute;
    bottom: -1.5px;
    right: -1.5px;
}

スクリーンショット 2019-11-23 23.56.57.png
微妙にはみ出る・・・

うまくいくパターン

css
.container {
    height: 100px;
    width: 100px;
    background: skyblue;
    position: relative;
}

.badge {
    padding: 0;
    background: green;
    color: white;
    height: 15px;
    width: 15px;
    font-size: 10px;
    transform: scale(0.6);

    position: absolute;
    bottom: -3px;
    right: -3px;
}

スクリーンショット 2019-11-23 23.56.21.png
うまくいきました!

なお、絶対位置は0指定でマイナスマージンをとってもよい(こちらも小数点以下指定でずれる)

css
.badge {
    padding: 0;
    background: green;
    color: white;
    height: 15px;
    width: 15px;
    font-size: 10px;
    transform: scale(0.6);

    position: absolute;
    bottom: 0;
    right: 0;

    margin-bottom: -3px;
    margin-right: -3px;
}

結の論

transformを使うときは、transform-originの存在を頭に置いておこう!

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5