Webページを取り込んだあと Auto Layout がずれる理由
ブラウザでは揃っていたカードの一枚が、Figma では4px下がっています。壊れたと指させるほどではありません。何が起きたのかを整理しました。
Webページを Figma に取り込みました。レイヤーパネルは埋まったのに、どこか噛み合いません。ブラウザでは揃っていたカードの一枚が4pxほど下がっていて、中央寄せだったナビゲーションが中央寄せのようなそうでないような位置にあります。壊れたと指させるほどではないのに、隣に開いたスクリーンショットとは明らかに違います。
この場合の原因はほぼ必ず Auto Layout です。つけてはいけない場所についています。対処が「Auto Layout をやめる」ではないので、理由を知っておく価値があります。ふたつのレイアウトシステムが本当に一致する場面と、ツールが当て推量している場面を見分けることが肝心なのです。
そもそも一致するはずのないふたつのエンジン
ブラウザは CSS でページを組みます。Flexbox、Grid、float、インラインフロー、マージンの相殺、文字を自分のボックスの外へ押し出す line-height、プラットフォームごとに違うサブピクセルの丸め。数十年分のルールで、その大半は一度きり効いてくる例外です。
Figma はフレームを Auto Layout で組みます。ずっと小さなシステムで、それは意図的です。方向がひとつ、間隔がひとつ、パディングが4つ、2軸の揃え方、そして子要素ごとの grow と stretch。ほぼこれで全部です。
Auto Layout は Flexbox の再実装ではありません。自転車とオートバイが似ている程度に似ています。ですから変換ツールが display: flex を読んで layoutMode: "HORIZONTAL" を入れるのは、ひとつの主張をしていることになります。このふたつのシステムはすべての子を同じ位置に置くという主張です。当たることもあります。厄介なのは「ほぼ当たる」ことが多い点で、そちらのほうが悪い。
静かに食い違う場所
Flexbox に見えて Auto Layout が再現できないケースを挙げます。
- flex アイテムのマージン。 CSS では子が自分のマージンを持てますし、
margin-left: autoで特定のグループだけ右に寄せることもできます。Auto Layout にはフレーム全体の間隔がひとつあるだけで、子ごとのマージンは存在しません。 - space-around と space-evenly。 Auto Layout が持つのは
SPACE_BETWEENです。残りふたつは余った空間の配り方が違い、それを再現する設定はありません。 - align-items: baseline。 サイズの違う文字が同じベースラインに乗る配置で、見出しや価格表示でよく使われます。Auto Layout はボックスの端と中央で揃えるので、ベースラインでは揃いません。
- 小数の flex-grow。
flex: 1はlayoutGrow: 1に移せます。flex: 2やflex: 0.5には移し先がありません。 - flex-wrap。 折り返した行は一行の行とは別の幾何であり、どこで折り返すかはキャプチャ時のコンテナ幅で決まります。
- テキストの再計測。 ツールが最もつまずくところです。内容に合わせて大きさが決まるテキストレイヤーは Figma が自分で測ります。Figma が持っているフォントで、Figma が計算したサイズで。その結果がブラウザと1pxでも違えば、スタック上のあとに続く兄弟要素がすべてずれます。
最後の項目のせいで、この問題は欠けていたフォントを入れたあとや、他人の環境でだけ現れることがよくあります。
それでもツールが適用する理由
Auto Layout のフレームで埋まったファイルは、絶対座標の四角形で埋まったファイルより良く見えるからです。デモ映えしますし、機能リストの一行になります。そしてよくあるケース、たとえば単純な行や間隔の揃ったカードグリッドでは、実際に良いのです。フレームのサイズを変えてもきちんと追随してくれます。
問題は、確かめずに「よくあるケース」と「わずかに外れているケース」を見分けられないことです。そして確かめるのは、確かめないより手間がかかります。
ではどうするか
すでに取り込んだファイルなら
おかしく見えるフレームを選び、レイアウトモードをなしにします。Figma の右パネルのレイアウト項目です。子要素は現在の位置を保つので、すでにずれているなら元に戻るのではなくその状態で固定されます。だからたいていは直すより取り込み直すほうが早い。
取り込み直す前にひとつだけ確認してください。そのページが使っていたフォントは自分の環境に入っていますか。代替フォントになるとすべてのテキストレイヤーが測り直され、文字幅が違うファイルはレイアウトをいくらいじっても合いません。どのフォントが足りないかは、ファイルを開いたときに Figma が教えてくれます。
ツールを選んでいる最中なら
ふたつのシステムが食い違ったときに何をするのか聞いてみてください。答えは三つしかなく、まともなのはひとつだけです。
- Flexbox を見つけたら全部に Auto Layout をつける。 速く、デモ映えし、静かにずれたファイルを渡してきます。
- 決してつけない。 常に正確で、まったく役に立ちません。正確だけれど編集がつらい絶対座標のレイヤーの山を受け取ります。
- 元を再現できるときだけつける。 正確で役にも立ちますが、ツールが Figma の挙動を実際に予測して比べる必要があります。
Snapture の判断のしかた
三つ目を選んでいて、仕組みは一段落で説明できるほど単純です。
キャプチャの時点で、どの要素がどこにあるかはすでに分かっています。レンダリングされたページを読んだので、子ごとにブラウザが計算した実際の矩形を持っているからです。レイアウトをつける前に、同じフレームを Figma のエンジンならどう扱うかをシミュレーションします。パディング、間隔、揃え方、grow の配分まで計算して、子ごとの予測矩形を出します。そしてふたつの組を比べます。すべての子がブラウザの置いた位置から 0.5px 以内 に収まればレイアウトをつけ、ひとつでも外れればそのフレームは絶対座標のままにします。
反対側にもうひとつ検査があります。Figma プラグインがレイアウトを適用したあと、子要素をもう一度測ります。今度は予測ではなく本物のエンジンを相手にです。同じ 0.5px を超えて動いたものがあれば、キャプチャした座標に戻します。テキストレイヤーは取り込み時に、どんなシミュレーションも見通せない形で再計測されうるので、この検査が要るのです。
実際の比率
実在のページに変換器をかけると、どれくらい厳しいかが分かります。実測ページに載せたものと同じ計測結果です。
| ページ | 総ノード | Auto Layout フレーム |
|---|---|---|
| linear.app | 2,082 | 261 |
| stripe.com | 1,592 | 99 |
| tailwindcss.com | 1,540 | 89 |
| github.com | 785 | 42 |
| developer.mozilla.org | 253 | 5 |
面白いのは MDN の行です。253ノードに対して Auto Layout フレームが5つというのは、ツールが失敗したように見えます。きちんと働いた結果です。MDN の本文レイアウトは主に文書フローと float で、Auto Layout はそれをまったくモデル化していません。だから関門がほぼすべてを却下し、正確な座標を残したのです。あのページではピクセルが合っていて Auto Layout がほとんどない、という取引が正解です。
対して Linear は、間隔の揃った flex 行でほぼ全体が組まれています。261のフレームが比較を通り、Figma でサイズを変えてもきちんと動きます。
まとめると
取り込んだあとの Auto Layout は、何かが検証したときだけ信用できます。Flexbox と Auto Layout は変換ツールを騙せるほど似ていて、ファイルをずらすほど違います。しかもその差は目に見える破損ではなく数ピクセルとして現れる。探すのに最も時間のかかる種類のエラーです。
ふたつが食い違ったときに何をするか答えられないツールは、確かめていないと考えて差し支えありません。
自分のページで試す 無料キャプチャ5回、全機能つき。カードも会員登録も不要です。English · 한국어 · 日本語 · 简体中文 · 繁體中文 · Español · Português · Français · Deutsch · Русский · Italiano · Bahasa Indonesia