stylusでcalcを使って自動で幅を設定しようとしたらうまくいかなかった
うまくいかなかったこと
単純なプラスはうまくいったのですが、マイナスがうまくいかず、マイナスに加えて割り算を組み合わせようとした場合も、うまく計算してくれませんでした。 ということで調べたことをまとめておきます。
単純なプラスするcalc(うまくいった)
width calc(100% + 60px)
難しく考える必要はなく、これでちゃんと描画されました。
単純なマイナスするcalc(うまくいかなかった)
calcで、スクリーンの横幅(100%)から、左右の20pxずつのマージンを引いた横幅を、ある枠に設定したい! とします。
width calc(100% - 40px)
でいいでしょう。と思いきや、ダメでした。
stylusでは、なにやら、 -
が前に付くことで、変数だと勘違い?? したりするんだとか。
ということで、 -
の前に、 \
(バックスラッシュ)をつけてあげるといいらしい。エスケープさせるということかな。(すんませんちゃんと調べてない、詳しくはご自身でお調べください)
width calc(100% \- 40px)
こうすれば、上手く効くようになりました。
引き算と割り算を同時に使うケース(うまくいかなかった)
135pxの横幅のものを、必ず画面の真ん中に配置したいという場合です。
入れ物に、 position: relative
をつけ、配置したいものに、 postion: absolute
をつけます。
そして、配置したいものの left
に設定するものは、
left calc((100%-135px)/2)
で良いはず・・・
と思ったら!!
なんと、HTMLでレンダリングされたinspectを見たら、 calc((-35%)/2)
と出ている・・・
なんでだ?? 違う違う!!!
これは、調べてみたらバグっぽかったです。
以下のように書いたら、思った通りに配置されました。
leftMargin = unquote('100% - 135px') left 'calc((%s) / 2)' % leftMargin
leftMargin
というのは、変数(自由に命名できる)を使っています。%
の後ろにleftMargin
(変数)を指定することで、%s
に入れ込むことができました
このタイプについては、 -
の前に、 \
(バックスラッシュ) つけてみてもダメで、やはり計算結果が変になったので注意が必要です。
stackoverflowでは2013年あたりの記事で書かれたものを参考にしましたが、2018年11月現在未だにこのやり方でないとうまくいかないようなので、stylus的に直す気は無いということでしょうか。
上下左右真ん中に配置したいケース
基本的には、先ほどのケースと同じです。 図のように、丸を左のボックスAの真ん中に配置したい! という場合です。
ボックスAに position: relative
をつけ、丸に position: absolute
をつけますね。
そして、丸に top
や left
を設定する時に、 calc
を使用したいわけです。
設置したい画像(=丸)の幅を、ボックスAの幅から引いて、二で割ると、丸の left
に相当しますね。
.A position relative display block flex-basis 30% float left .B position absolute background-color #fff diameter = 50px width diameter height diameter border-radius 'calc((%s)/2)' % diameter topMargin = unquote('100% - 50px') top 'calc((%s)/2)' % topMargin leftMargin = unquote('100% - 50px') left 'calc((%s)/2)' % leftMargin
注: A
の flex-basis
は、それだけではflexになってはくれず、その親に display: flex
を入れておく必要があります。念のため。詳しくはそれについて書いたこちらの記事を参照のこと。
本当は、 topMargin
および leftMargin
で 50px
と書いているところを diameter
という変数を入れて、丸の直径 diameter
を変えれば全て自動で変わるようにしたかったのですが、 unquote
の中に calc
を入れるとうまくいかなかったので、断念して、 50px
とベタ書きした形になります。
せっかく変数が使えると思うと、もう少し複雑な計算式も書き込めるようにしてほしい、と思う一方で、レンダリングに時間がかかってしまうのかもしれないと思うので、できる範囲で使って行きます。
細かい間違えやすい点(補足)
ちなみに、
○ left 'calc((%s)/2)' % leftMargin
こうするべきところを
× left 'calc(%s/2)' % leftMargin
というように、分子をカッコでくくるのを忘れると、上手く効きませんでした。(chromeで確認)
さらに、
○ leftMargin = unquote('100% - 50px')
のところで、マイナス記号の間のスペースをなくしたところ、これも効きませんでした(同じくchromeで確認)
× leftMargin = unquote('100%-50px')