Firefox 147.0、Mastodon v4.6.0-nightly.2026-01-15 の時に、マストドンの投稿を選択してテキストエディタなどに貼り付けたら、URLが https:// の後に改行されて、その後とは分断されていた。その投稿がここの投稿だったのでプラグインActivityPubの更新が原因かと思ったが違った。mastodon.socialは常に更新されているし、Firefoxの更新とも重なっているので、どちらかが原因ではないかと思う。ただし、v4.1.25で更新が止まってるmstdn.jpでも改行されたし、Edgeでは改行されなかったので、Firefoxが一番怪しい。しかし、Geminiに尋ねたところ、Firefoxのバグではなさそうだった。
いろいろと考察して、原因らしきものが分かったので、同じ症状を再現する短いコードを作ることができた。それは次のとおりである。
<p>
上の行<br>
<a href="" class="unhandled-link"><span class="invisible">https://</span><span class="ellipsis">example.com/tag/</span><span class="invisible">test/#hash</span></a><br>
下の行
</p>
<style>
p {white-space: pre-wrap;}
.invisible {
font-size: 0;
line-height: 0;
display: inline-block;
width: 0;
height: 0;
position: absolute;
}
.ellipsis::after{content: "…";}
</style>
このコード(cssはWordPressと重ならないように変えてある)は次のように表示される。
Firefoxを使っている人は、この「上の行」から「下の行」までをコピーしてテキストエディタに貼り付けてほしい。URLが https:// の後で改行されると思う。次のように表示される。
上の行
https://
example.com/tag/test/#hash
下の行
p {white-space: pre-wrap;}がp {white-space: normal;}だったら改行されないし、.invisibleの position: absolute; が position: relative; でも改行されない。この2か所が原因らしい。
この件についてGeminiに尋ねてみた。

次のコードについて教えてください。このコードで表示されるaタグは example.com/tag/… だけですが、表示された「上の行」から「下の行」までをコピーした時に、Firefox では https://で改行されてしまいます。p {white-space: pre-wrap;}が無ければ改行されません。あるいは、.invisibleがposition: relative;なら改行されません。Edgeではどちらも改行されることがありません。その理由を解説してください。(コードは略、上記と同じ)

ちょっと勘違いしているようです。改行されるのはhttps://の後で、次のようにURLが分断されるのです。(表示は略、上記の通り)
大変失礼いたしました。現象を正しく理解しました。
コピーした際に
https://(1番目のspan)とexample.com/...(2番目のspan)の間で意図しない改行が挿入されるという現象ですね。これは、Firefoxにおける**「インライン要素の物理的な分離」と「
pre-wrapによる折り返し計算」の相互作用**によるものです。論理的な理由は以下の3点に集約されます。
1. absolute による「行(Line Box)」の分断
Firefoxにおいて、要素を
position: absolute;にすると、その要素は通常のインライン・フロー(文字が横に並ぶ流れ)から完全に切り離されます。
- Firefoxの解釈:
.invisibleを「空中に浮いた独立したパーツ」として扱います。すると、ブラウザのコピー処理エンジンは、その直後にある通常のspan(.ellipsis)との間に**「論理的な連続性がない」**と判断し、別々の行としてテキストを抽出しようとします。relativeならOKな理由:position: relative;はフロー内に留まるため、ブラウザは「文字が繋がっている」と認識し、改行を挟みません。2. white-space: pre-wrap; が引き起こす「幽霊の改行」
通常、要素が
width: 0;であれば視覚的に改行は起きません。しかし、white-space: pre-wrap;が指定されていると、Firefoxは「要素の境界で折り返せる可能性」を極めて厳密に計算します。
absolute要素(https://)が終わった直後、次のspanが始まるポイントで、Firefoxは**「ここがフローの接続点(かつ折り返し可能地点)」**であると内部的にマーキングします。コピー時には、この「見えない接続点」を「行の切り替わり」として出力テキストに反映してしまい、結果としてhttps://の直後に改行が挿入されます。3. Edge(Chromium)との設計思想の違い
この挙動の差は、ブラウザが「コピー用テキスト」を生成する際の優先順位の違いから生まれます。
- Firefox: DOM構造とCSSの配置プロパティを重視します。
absoluteでフローが分断されていれば、それをテキストデータ上の区切り(改行)として忠実に再現しようとする傾向があります。- Edge (Chromium): 最終的な見た目の「座標」を重視します。コピー範囲の各文字が「同じY座標(高さ)」に並んでいる場合、CSSでフローが分断されていようがいまいが、それらを1行の文字列として連結してクリップボードに送ります。
まとめ:なぜこの条件で発生するのか
pre-wrapがある場合: 要素の境界を「改行可能なポイント」として強く意識するため、コピー時に改行が入りやすい。.invisibleがabsoluteの場合: インラインの連続性が失われ、Firefoxが「別の塊」として認識するため、境界で改行される。回避策のアドバイス
もしこの構造を維持したままFirefoxでの改行を防ぎたい場合は、
.invisibleに対してposition: absolute;を使う代わりに、以下のようにフローを壊さない非表示化を検討してみてください。CSS
.invisible { display: inline; /* block化しない */ font-size: 0; line-height: 0; opacity: 0; pointer-events: none; /* position: absolute; を避ける */ }この現象について、さらに特定のブラウザバージョンや、他のスタイルとの兼ね合いで気になる点はありますか?

私のサイトでないので、position: absolute;をコメントアウトすることはできません。アドオンでCSSを変えることができてposition: relative;にはできます。それで問題ないですか?
結論から申し上げますと、アドオンを使って
position: relative;に変更することは、今回の問題を解決する非常に論理的で正しいアプローチです。その変更によって解決する理由と、懸念点がないかについて解説します。
なぜ position: relative; で解決するのか
Firefoxがコピー時に改行を入れてしまう最大の理由は、先述の通り 「インライン・フロー(文字の並び)の分断」 です。
absoluteの時: 要素が通常の文章の流れから「完全に浮いた」状態です。Firefoxのコピー処理エンジンは、浮いている要素(https://)と、地面(フロー)にいる要素(example.com...)を「別の段落」のように認識し、その境目に改行を挿入します。relativeの時: 要素は「通常の文章の流れの中」に留まったまま、位置だけを微調整できる状態になります。Firefoxは「同じ行の中に文字が連続している」と認識するため、pre-wrapが効いていても、不要な改行を挿入せずにコピーできるようになります。副作用の確認(問題ないかどうかの判断)
absoluteをrelativeに変える際、サイトの見た目が崩れないか以下の点だけ確認してください。
- 要素の「占有スペース」:
absoluteは本来スペースを占有しません(width: 0; height: 0;になっているのはそのためです)。relativeに変えても、すでにwidth: 0; height: 0;やfont-size: 0;が指定されているため、文字が重なったり隙間が空いたりするリスクは極めて低いです。- レイアウトの崩れ:
.invisible自体にtopやleftなどのプロパティが設定されている場合、relativeにすると位置が少しズレる可能性があります。しかし、ご提示のコード(非表示にすることが目的の設定)であれば、まず問題ありません。結論
「
relativeに上書きする」のは、非常にスマートな解決策です。 Firefoxにおいて「データの連続性」を維持しつつ、視覚的な影響を最小限に抑えることができるため、その方法で進めて問題ありません。もし設定後に「少し隙間が空いてしまった」などの現象が起きた場合は、追加で
display: contents;やfloat: left;などを試す方法もありますが、まずはrelativeへの変更で様子を見るのがベストです。その他、アドオンの設定方法などで不明な点はありますか?

p {white-space: pre-wrap;}の方を変えるのは良くないですか?
p {white-space: pre-wrap;}を変更することでも改行問題は解決しますが、**「どちらの設定がより重要か(壊したくないか)」**という観点から、慎重に判断する必要があります。結論から言うと、
white-spaceを変えるのは 「サイト全体の読みやすさに影響を与えるリスクがある」 ため、基本的にはposition: relative;で対応する方が安全です。その理由を論理的に整理します。
1. white-space: pre-wrap; の役割
このプロパティが指定されている理由は、主に以下の2点です。
- ソース内の改行を反映させるため:
brタグを使わなくても、Enterで改行した部分をそのまま表示したい場合。- 長いURLなどの自動折り返し: 枠からはみ出すような長い文字列を、端で自動的に折り返させるため。
これを
normalなどに変えてしまうと、本来改行されるべき場所が繋がってしまったり、逆に長い単語が枠を突き抜けたりして、レイアウトが崩れる可能性があります。2. なぜ pre-wrap を変えると解決するのか
Firefoxがコピー時に改行を入れるのは、「
pre-wrap(改行を厳密に扱う設定)」と「absolute(フローの切断)」が組み合わさったときだけです。
pre-wrapをnormalやnowrapに変えれば、Firefoxは「要素の境界にある見えない改行」を無視するようになるため、確かにコピー時の問題は消えます。3. どちらを変えるべきかの比較
変更対象 メリット デメリット・リスク .invisibleをrelativeにする他の要素に一切影響を与えず、コピー時の分断だけを直せる。 特になし(今回のコード構成なら安全)。 pのwhite-spaceを変えるコピー時の改行は確実に消える。 段落内の他のテキストの改行が消えたり、長いURLが枠を突き出したりする可能性がある。
結論:どちらが「良い」か
アドオンで特定の不具合を修正する場合、**「影響範囲を最小限にする」**のが鉄則です。
pタグのスタイルを変えると、そのpの中にある全てのテキストの挙動が変わってしまいます。.invisibleのスタイルを変えるのであれば、その非表示にされている特殊なスパンだけに影響を限定できます。したがって、
position: relative;に変更する方が、サイトの本来のデザインを壊すリスクが低く、より論理的な解決策と言えます。もし「どうしても
white-spaceを変えたい」という場合は、以下のように対象を限定して上書きすることをお勧めします。CSS
/* p全体ではなく、aタグの中に限定して影響を抑える */ a.unhandled-link { white-space: nowrap; }まずは
relativeへの変更を試してみて、もし万が一表示に違和感が出た場合にのみ、こちらの方法を検討するのがベストです。実際に
relativeを適用してみて、表示に変化はありましたか?

今回、EdgeとFirefoxで動作が異なりましたが、どちらの方が正しい動作ですか?
結論から申し上げますと、**「どちらも仕様(W3Cの規格)に違反しているわけではなく、実装方針の設計思想が異なる」**というのが正確な答えですが、ユーザーの利便性の観点からは Edge(Chromium)の方が「期待される動作」に近いと言えます。
なぜこのような「正解のない違い」が生まれるのか、論理的な背景を解説します。
1. 「コピー時の挙動」は標準化されていない
実は、ウェブブラウザの標準規格(HTMLやCSSの仕様)では、「画面上のテキストを選択してコピーした時に、どのようなプレーンテキストを生成すべきか」という詳細なアルゴリズムは定義されていません。
そのため、各ブラウザのエンジン(FirefoxのGecko、Edge/ChromeのBlink)が、独自に「ユーザーにとってこれがベストだろう」と推測して実装しています。
2. Firefoxの設計思想:構造に忠実
Firefoxは、**「DOM構造(HTMLの並び)とCSSの指定を厳密に反映させる」**という考え方が強いです。
white-space: pre-wrap;が指定されている。position: absolute;で要素が分断されている。- この状況では、Firefoxは「この2つの要素は論理的に切り離された別個のデータである」と解釈します。
たとえ視覚的に1行に見えていても、内部的な「データの繋がり(フロー)」が切れていれば、それを改行として出力するのは、ある種「コードに忠実な」動作と言えます。
3. Edge(Chromium)の設計思想:視覚に忠実
EdgeなどのChromium系ブラウザは、**「ユーザーが画面で見ている状態をそのままテキスト化する」**という考え方を優先しています。
- CSSでどう分断されていても、最終的なレンダリング結果(座標情報)を確認。
- 同じ行の高さ(Y軸)に並んでいれば、1つの連続した文字列としてコピー。
ユーザーからすれば「1行に見えるものは1行としてコピーしたい」のが普通ですので、**実用面ではEdgeの動作の方が「直感的で正しい」**と感じられます。
結論
- 学術的・仕様的な忠実さ: どちらも間違いではない(強いて言えば、構造を重視する Firefox は開発者寄り)。
- UX(ユーザー体験)としての正しさ: 視覚的な結果を優先する Edge が優れている。
Firefoxは伝統的に「構造」を重んじる傾向があり、今回のような特殊なCSSレイアウト(非表示テキストを絶対配置で挟む手法)において、その厳格さが「余計な改行」という形で裏目に出てしまっている形です。
ですので、あなたがアドオンで
relativeに修正して「データの繋がり」を教えてあげることは、Firefoxの厳格な解釈を「1行のテキスト」として正しく導くための、非常に理にかなった補正作業だと言えます。他にご不明な点や、コードの挙動で気になる部分はありますか?

なるほど。ありがとう。

コメント