言語を切り替えると配置が崩れる:文字幅を前提にした設計
遊びをつくる執筆にClaudeを使用しています。

ボタンが三つ並んだ操作バーを作る場面を考えてみます。日本語では「ヒント」「一手戻す」「一時停止」と短く収まり、枠にぴったり入っています。ところが表示を英語に切り替えると、ボタンの文字が枠からはみ出したり、隣のボタンに重なったりします。さらに英語の説明文が盤面の下で三行に増え、下のボタンが画面の外へ押し出されます。 この記事で確かめるのは、このような崩れが「言語のせい」なのか「幅を文字列に固定した設計のせい」なのかです。結論を先に言えば、後者です。日本語と英語では文字列の長さも、折り返せる場所も違います。その差を前提に、最初から余裕を持った枠で作っておけば、切り替えで配置は壊れにくくなります。 以下では、崩れが起きる仕組みを整理し、アソバースの公式作品の確認済み事項から「設計から読み取れること」を拾います。そのうえで、余裕を持たせる最小のコードと、自分で行える検査の手順を示します。記事内に実測値や検査結果は出てきません。数値は、読者が自分の環境で確かめるものとして扱います。
この記事の目次
崩れの原因は「枠の幅が文字列に依存している」こと
配置が崩れる場面の多くは、次の二つのどちらかです。
- 枠の幅を固定している(例:ボタンの幅を決め打ちにしている)ため、長い文字列が収まらない
- 枠の幅は伸びるが、伸びた分を受け止める余白がなく、隣の要素を押し出す
どちらも、枠の大きさを「日本語で作ったときの文字列」から決めたことが出発点です。開発中に確認する言語が一つだけだと、この前提に気づく機会がありません。
ここで大事なのは、崩れは切り替えの瞬間に初めて生まれるわけではない、という点です。もともと文字列の長さに余裕のない設計だっただけで、別の言語がそれを露出させます。同じ問題は、同じ言語の中でも起こります。たとえば将来ボタンの文言を少し長くしたとき、プレイ画面を拡大して表示領域が相対的に狭くなったとき、文字サイズを大きくして使う人が来たときです。
したがって、考え方は「言語ごとに配置を調整する」ではなく「文字列の長さが変わっても成立する枠にする」へ切り替えるのが近道です。
日本語と英語で変わるもの
一般に知られている範囲で、二つの言語の違いを整理します。どちらも傾向であり、文言ごとに例外があります。
- 文字の幅、日本語:全角文字が中心で、一文字ごとの幅がそろいやすい、英語:文字ごとに幅が違い、単語の長さで全体の幅が決まる
- 折り返し、日本語:文字の間で折り返せる場面が多い、英語:基本は単語の区切り(空白)で折り返す
- 長い語、日本語:熟語は短く収まることが多い、英語:長い単語は途中で折り返せず、枠からはみ出しやすい
- 文量、日本語:同じ意味でも文字数は少なめになりやすい、英語:文字数は増えやすい
ただし「英語の方が必ず長い」とは言えません。ボタンの短い語、たとえば「Undo」と「元に戻す」では、見た目の幅が逆転することもあります。数値の比較ではなく、自分の文言を実際に表示して確かめる必要があります。
設計に効くのは、次の三点です。
- 日本語は、文字の間で折り返せるぶん、枠が狭くても崩れにくい場合があります。ただし、ボタン内で意図しない折り返しが起きると、一文字だけが次の行に落ちるなど読みにくくなります。
- 英語は、長い単語や、空白のない文字列(ファイル名、見出しの複合語など)で枠をはみ出しやすくなります。
- 同じ操作でも、短い言い方と説明的な言い方があります。「ヒント」に対する英語を説明的にすると、ボタンの幅が一気に増えます。文言そのものを短くする判断も、配置設計の一部です。
公式作品の確認済み事項から読み取れること
アソバースの公式13作品について、確認済みなのは次の点です。ここから先は「設計から読み取れること」であり、開発者の意図の断定ではありません。
言語の変更で進行を保つ
13作品はサイトの日本語/英語設定に合わせて表示を切り替え、言語変更とプレイ画面の拡大で進行を保つ、とされています。ここから読み取れるのは、表示(文字列と配置)と進行(盤面・手数・記録など)が分けて扱われている可能性です。表示を作り直しても進行の状態が失われない構造になっている、と考えると、この仕様の説明がつきます。
自作のゲームでも、同じ分離が役に立ちます。文字列を差し替える処理が、進行の状態を初期化してしまう設計だと、言語を切り替えた瞬間に盤面が最初に戻ります。具体的にどう実装されているかは公開情報にないため、作品を開いて、切り替え前後で手数や盤面が変わらないかを自分で確かめてください。
狭い画面での横スクロール
「WAVE / WAVE」は、狭い画面ではステップが横スクロールになる、と確認されています。16ステップという並びを無理に縮めず、はみ出す分を横に逃がす設計だと読み取れます。幅が足りないときに、文字や部品を押しつぶすのではなく、スクロールで受け止める選択肢があることの実例です。
ただし、何ピクセルの幅で切り替わるのか、どの部品がスクロールするのかは確認済み事項にありません。作品を狭い幅で開いて、どこが動いてどこが動かないかを確かめてください。
タイトルの文字組みは作品ごとに違う
作品ごとにタイトルの文字組みが異なります。縦組みの明朝、手描き文字、郵便ラベル、夜の標識、光の幾何学、メニュー風などです。縦組みは、文字が増えたとき横ではなく縦に伸びます。手描き風の文字は、文字数による伸び方が読みにくい場合があります。つまり、タイトルの枠に必要な余裕は、文字組みの種類ごとに伸びる方向が違います。
言語を切り替えたときにタイトルがどう見えるかは、作品によって違う可能性があります。タイトルが文字として表示されているのか画像なのかも、確認済み事項にはありません。作品を開いて、日本語と英語の表示を見比べてください。
作者が入力した文は書き換えられない
アソバースの日本語/英語の切り替えは、作者が入力した作品名や紹介文を書き換えません。投稿者の立場では、作品名や紹介文が一つの言語で入力されていれば、サイトの表示言語を切り替えても、その部分は入力した文字列のままです。つまり、作品名や紹介文がカードや詳細ページの枠で長すぎないかは、作者側で考える必要があります。
関連して、投稿画面の「紹介文と遊び方を作成」は、選択言語の下書きを作ります。「この文章を使う」を押した場合だけ反映され、生成だけで公開はされません。言語を変えて下書きを作れば、長さの違いを見比べる材料になります。ただし、生成には利用者ごとに1時間3回という上限があるため、使い切る前に、どの言語で何を確かめるかを決めておくと無駄がありません。
余裕を持たせる設計の最小コード
次のHTMLは、一つのファイルで動く最小の例です。ボタンの幅を固定せず、折り返しと最小幅で受け止めます。説明文の枠には最小の高さを持たせ、文が伸びても下の部品が急に動かないようにしています。「長文テスト」ボタンで、すべての文言を二倍に伸ばして試せます。
<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
body{font-family:system-ui,sans-serif;padding:16px}
.bar{display:flex;flex-wrap:wrap;gap:8px;max-width:360px}
.btn{flex:1 1 auto;min-width:6em;padding:.6em .9em;
border:1px solid #567;border-radius:8px;background:#eef;
line-height:1.4;overflow-wrap:anywhere}
.panel{max-width:360px;margin:12px 0;padding:12px;
border:1px solid #ccc;min-height:4.5em}
</style>
<div class="bar" id="bar"></div>
<div class="panel" id="msg"></div>
<button id="sw">日本語 / English</button>
<button id="lg">長文テスト</button>
<script>
const T={
ja:{hint:"ヒント",undo:"一手戻す",pause:"一時停止",msg:"盤面の説明がここに入ります。"},
en:{hint:"Show a hint for the next move",undo:"Undo last move",pause:"Pause",msg:"The explanation of the board goes here."}};
let lang="ja",stress=false;
const game={moves:0}; // 進行の状態は表示と分けて持つ
function render(){
bar.innerHTML="";
for(const k of ["hint","undo","pause"]){
const b=document.createElement("button");
b.className="btn";
const s=T[lang][k];
b.textContent=stress?s+" "+s:s;
bar.append(b);
}
msg.textContent=T[lang].msg+" ("+game.moves+")";
}
sw.onclick=()=>{lang=lang==="ja"?"en":"ja";render();};
lg.onclick=()=>{stress=!stress;render();};
render();
</script>このコードのポイントは三つです。
- ボタンの幅は min-width と flex で決めています。 幅の決め打ちはしていません。短い文言なら最小幅、長い文言なら内容に合わせて広がり、広がりきれなければ次の行へ回ります。
- overflow-wrap:anywhere で、空白のない長い文字列も折り返します。 英語の長い単語や、ファイル名のような文字列がはみ出しにくくなります。ただし、単語の途中で折れるため、見た目の好みは分かれます。重要な語が割れる場所は、文言のほうを短くする判断も必要です。
- 進行の状態(game)は、描画関数の外に持っています。 言語を切り替えて render を呼び直しても、手数などは変わりません。確認済み事項の「言語変更で進行を保つ」と同じ方向の考え方です。ただし、公式作品がこの形で実装されているという意味ではありません。
自作のゲームに取り入れるときは、実際の部品に合わせて最小幅や折り返しの規則を決め直してください。
自分で行う検査の手順
余裕があるかどうかは、見た目の印象ではなく、同じ手順で何度も確かめるのが確実です。
準備するもの
- 画面に出る文言の一覧(ボタン、見出し、説明文、エラー、結果表示)
- 日本語と英語の両方の文言
- ブラウザの幅を変える手段と、ページの拡大・縮小の操作
- 記録用の表
手順
- 文言を一覧にし、一つの枠に入る文言のうち、いちばん長そうなものを各言語で選びます。
- 選んだ文言を二倍の長さにして表示します(上のコードの「長文テスト」と同じ考え方です)。二倍で崩れなければ、文言を多少直しても耐えられる余裕があると判断できます。
- ブラウザの幅を、広い・中くらい・狭いの三段階にします。それぞれで日本語と英語を表示します。
- ページの拡大を二段階(標準と大きめ)にして、手順3を繰り返します。
- 言語を切り替える前に、盤面・手数・残り時間・得点など、進行の状態をメモします。切り替えたあと、同じ値が保たれているかを見ます。
記録の取り方
一つの枠につき、言語(2)×幅(3)×拡大(2)の12通りを、1回ずつ表に記録します。各行には、次の結果から当てはまるものを書きます。
- はみ出し(枠の外へ文字が出る)
- 重なり(隣の部品に被る)
- 欠け(文字が隠れて読めない)
- 押し出し(別の部品が画面外へ動く)
- 問題なし
同じ組み合わせを二度見たときに結果が違う場合は、描画のタイミングに原因がある可能性があります。その行には「不安定」と書き、あとで原因を探します。
結果の読み方
- 日本語だけで崩れるなら、全角の長い語や、意図しない折り返しを疑います。
- 英語だけで崩れるなら、長い単語、空白のない文字列、文言の長さを疑います。
- 両方で、狭い幅か拡大時だけ崩れるなら、言語ではなく枠の設計の問題です。
- 切り替え後に進行の状態が変わるなら、表示と進行が分かれていません。
起こりやすい誤り
- 日本語の見た目だけで枠を決める。 作っている最中に英語を一度も見ないと、最小幅が足りているか分かりません。
- ボタンの幅をピクセルで固定する。 文言を少し変えただけで崩れ、ページの拡大にも弱くなります。
- 英語の長い文言をそのままボタンに入れる。 配置で受け止める前に、「Show a hint for the next move」を「Hint」にするなど、文言を短くする選択肢を検討します。
- 言語の切り替えで画面を丸ごと作り直し、進行を初期化する。 表示を作り直すのは構いませんが、進行の状態は別に持ちます。
- タイトルや見出しの飾りを、文字数の変化に備えず作る。 縦組みなら縦に、横組みなら横に伸びます。伸びる方向を確認しておきます。
- 確認を一回で済ませる。 幅・拡大・言語は掛け合わせで効きます。一つずつ確かめても、組み合わせで崩れることがあります。
次の行動
まず公式作品のうち、狭い画面で横スクロールする「WAVE / WAVE」と、タイトルの文字組みが特徴的な作品を一つ開き、日本語と英語を切り替えて見比べてください。そのとき、切り替え前後で進行の状態が保たれているかも確認します。そのうえで、自作のゲームの文言一覧に二倍の長さを当てて、上の12通りの表を一つの枠から埋めてみてください。
参考資料
- MDN Web Docs(CSSの min-width、overflow-wrap、flex-wrap の各解説)

