16
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

translate: transform() と calc() の演算結果の問題と、IEへの対応

Last updated at Posted at 2017-01-18

TL;DR

結論:translate() x calc() するときはtranslateX()translateY()をがんばって書くか、書き方を変えよう。

CSSの transform() と calc() を合わせた演算結果がブラウザによって異なる問題

まずはデバッグしてみよう。テストのために、以下のようなHTMLとスタイルシートを用意した。

HTML
<div class="transform-tester">
  <p>This paragraph should be transformed to center-center.</p>
</div>
CSS
  .transform-tester {
    position: relative;
    width: 200px;
    height: 200px;
    background-color: red;
  }

  .transform-tester > p {
    position: absolute;
    top: 50%;
    left: 50%;
    margin: 0;
    font-size: 30px;
    white-space: nowrap;
  }

この時点では、子要素を親要素の中央にabsolute配置したのみである。中央寄せではなく、要素の座標(0,0)を移動しただけであることに注意。IEも含めて、以下のようにちゃんと想定通りの配置となる。

Screen Shot 2017-01-18 at 5.58.20 PM.png ## translate() + calc() してみよう

さて、ここで以下のようなスタイルを <p> に付与するとどうなるだろうか。例えば、自身の要素の半分だけ縦位置を上げてから、1em分さらに上げてみるということをしてみよう。1

CSS
  .transform-tester > p {
    transform: translate(0, calc(-50% - 1em));
  }
Screen Shot 2017-01-18 at 6.04.29 PM.png だいたい思ったとおりの位置になった。これは、**Chrome / Safari / Firefoxで同等の結果**[^2]だ。

IE (IE11, IE10, IE9)

Screen Shot 2017-01-18 at 5.58.20 PM.png 変わってない。念のため`-ms-`プレフィックスを付与してみたが変わらない。調べてみたら[stack overflow](http://stackoverflow.com/questions/21142923/ie-10-11-css-transitions-with-calc-do-not-work)に答えがあった。**IEでは、transform()とcalc()の合成演算を無視する**。

答え1

分けて書けば、どのブラウザでも想定通りに描画される。
  .transform-tester > p {
    transform: translateY(-50%) translateY(1em);
  }

わかりやすい。わかりやすいが、2回同じことを書くのは気持ち悪いという場合は、以下の答えもある。

答え2

  /* 最初に書いたCSS */
  .transform-tester > p {
    position: absolute;
    /* この時点で -1em しちゃえばいいじゃない */
    top: calc(50% - 1em);
    left: 50%;
    margin: 0;
    font-size: 30px;
    white-space: nowrap;
  }

  /* あとから付け加えたCSS */
  .transform-tester > p {
    transform: translate(0, -50%);
  }

ただし、calc()演算は(sassの演算もそうだが)ビジネスロジックとの関係性が重要だ。最終的にどう表示されるかではなく、ロジックに基づく計算式をコードとして残しておき、かつそれをそのままレンダリングに使うことのほうが保守観点から有効な場合があることには注意されたい。

  1. あくまでも例である。実際にtranslate() x calc()しなければならないケースの場合は、より複雑な計算が必要になるだろう。

16
9
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
16
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?