ボタンのテキスト長くしたら、隣のアイコンがぺしゃんこに。flex-basisが原因だった
「送信」って書いてあるボタン、あとから「お問い合わせ内容を送信する」に文言を変えたくなること、ありますよね。先日、まさにその修正をすることになって、テキスト変えるだけなら余裕だと思って、ささっと変更したんです。
そしたら、画面を確認したとたん、ボタンが崩壊してました。
左側にあるはずのアイコンが、幅ゼロってくらい潰れてて、もはや縦線のような姿に。
なぜ? からの再現
問題のコードはこんな感じでした。
<button class="btn">
<span class="btn-icon">📩</span>
<span class="btn-text">送信</span>
</button>.btn {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 24px;
}
.btn-icon {
/* 特にサイズ指定はしてない */
font-size: 20px;
}
.btn-text {
/* こっちも特に何もない */
}テキストが「送信」のときは問題なかったんです。アイコンも20px相当で表示されてたし、ボタン全体もキレイに収まってました。
でも「お問い合わせ内容を送信する」に変えた瞬間、アイコンがギュッと。デベロッパーツールで見たら、アイコンの要素、幅がほぼ0pxに。
flexの初期値を侮ってはいけない
それで、思い出したのがflexアイテムの初期値。
.btn-iconにflex-basisを指定していなかったので、デフォルトのautoが効いてる。flex-basis: autoは「コンテンツの本来のサイズを基準にする」という指定なんですけど、flex-shrinkの初期値も1なので、隣のアイテムがでかくなると容赦なく縮められる。今回のボタンは親要素の幅に制限があったので、長くなったテキストを優先して、アイコンが犠牲になったわけです。
flex-shrink: 0で解決
というわけで、アイコンに「縮まなくていい」と指示します。
.btn-icon {
flex-shrink: 0;
font-size: 20px;
}これでテキストがどんなに長くなっても、アイコンの幅は確保される。ただし親要素の幅に制限があるせいで、今度はボタン全体が右側にはみ出してしまうんですよね。今回は親要素の max-width を少し緩めてボタンが伸びる余地を作ることで、はみ出しを解消しました。レイアウト全体への影響も最小限で済んだので助かりました。
ちなみにテキストを折り返したくなかったので、テキスト側もこうしておきます。
.btn-text {
white-space: nowrap;
}アイコンのサイズって本来固定では?
でもこの対応をしてて思ったのは、アイコンって急に大きくなったり小さくなったりするものじゃないから、サイズを固定しちゃったほうが自然なんじゃないかと。
ということで、flex-basisも含めてこうしました。
.btn-icon {
flex: 0 0 24px;
font-size: 20px;
}font-sizeと同じ20pxにしようかとも思ったんですが、絵文字の左右にできる微妙な余白のせいでちょっと窮屈に見えたので、ブラウザで確認しながら24pxに微調整しています。こうしておけば「伸びない、縮まない、基本サイズは24px」で安心です。
まあ実務的にはflex-shrink: 0だけでも十分通用しますけど、自分の中ではこれでスッキリでした。
というわけで、テキストの折り返し防止も合わせて、最終的にこんなコードに落ち着きました。
最終的に
.btn {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 24px;
}
.btn-icon {
flex: 0 0 24px;
font-size: 20px;
}
.btn-text {
white-space: nowrap;
}flex-basisは、アイコン周りの微妙な余白を見ながら 24px に微調整しました。font-sizeと同じ20pxだと、絵文字の左右にできる余白のせいでちょっと窮屈に見えたんですよね。
テキストが「送信」でも「お問い合わせ内容を送信する」でも、アイコンは24pxを保ってくれます。
今回はテキスト変更という些細な修正になるつもりが、flex-basisの初期値と向き合うハメになりました。こういう小さな引っかかりをちゃんと理解しておくと、次からはスムーズに原因にたどり着けるはず。
