左右marginで任意の比率を保つ

元ネタは ながしまさんのツイートから。

固定幅の要素の左右marginでauto値っぽい挙動を保ちつつ、その比率を任意のものにしたいとのこと。実現するには CSS Values and Units Module Level3のcalc()しかない。

とりあえず、適応したい要素を200*150pxのdivとして、margin-leftmargin-rightの比2対3になるように書いてみた。

div{
    margin: 0;
    margin-left:  calc(100%*2/5 - 200px*2/5);
    margin-right: calc(100%*3/5 - 200px*3/5);
    width: 200px;
    height: 150px;
    background: red;
}

できた。

2対3なら合計分を分母にとった数を100% - 200pxの式にそれぞれ掛けてあげる。

その後、いろいろ検証的なことをして以下で FTWとなった。

div{
    margin: 0;

    margin-left:  calc((100% - 200px) * 2 / 5);
    margin-right: calc((100% - 200px) * 3 / 5);

    width: 200px;
    height: 150px;
    background: red;
}

上記のように四則演算で丸括弧を使って計算を優先させる構文がcalc()でも使える。

実はながしまさんに最初のリプライを送るときにcalc()の中で()を使うのは試していたんだけど、(100% - 200px)の部分を以下のようにスペースなしで書いていて、それだと動かなかったのでやめていた。

div{
    margin-left:  calc((100%-200px) * 2 / 5);
    margin-right: calc((100%-200px) * 3 / 5);
}

加減式の場合、 負の値への対応で前後にスペースが必要なのだとか。言われてみれば確かにそうだ。CSS Variablesで 変数にハイフンが入った時に区別できないから、という意見ももらった。どちらもなるほどですね。


追記。

marginの左右両方でcalc()を指定しているけど、 どちらかでcalc()していればもう一方はauto値でよいようだ。

div{
    margin-left:  calc((100% - 200px) * 4 / 5 );
    margin-right: calc((100% - 200px) / 5 );
}
div{
    margin-left: auto;
    margin-right:  calc((100% - 200px) / 5 );
}
div{
    margin-left:  calc((100% - 200px) * 4 / 5 );
    margin-right: auto;
}

上記3パターンは全て同じことになる。

僕にはもう1,2歩先までコードを簡略化する発想がどうもできないっぽい。なのでCSSおじさんは名乗れない。