miyaoka.dev

Twitter Web の縦長画像をフル表示する

少し前にアプリ版の Twitter で TL の画像表示が固定比率でなくなり、縦長のものも表示されるようになった(あまり縦長すぎると切られるが)。で、web 版でも縦長にしたいなと思って style を上書きするようにしてみた。

なにをやっているかというと、Twitter では画像を固定比率にするために背景画像が使われている。でも実は隣に同内容の img 要素もあってそちらは opacity:0 で非表示になっている。なので、これを opacity:1 にするだけで普通の画像が見れる。ただ、img 要素は親要素に対して 100%表示になっていてここで比率が固定されてしまっているので、それらを全部解除することで画像本来の比率での表示ができるようになる。

タイムラインは縦長になるが、クリックしなくても最初から内容がちゃんと見えるようになるのでだいぶ便利になった。

縦長フル表示。アプリ版と違ってどんなに長くても表示する
縦長フル表示。アプリ版と違ってどんなに長くても表示する

[role="article"] [role="link"] *
{
  position: relative !important;
  padding-bottom: 0 !important;
  margin: 0 !important;
}
[role="article"] [role="link"] img {
  opacity: 1 !important;
}

style についてはこれを Chrome 拡張の Stylusを使って適用させるようにした。これでだいたい目的は達成されたのでしばらく運用していたのだが、ちょっとセレクタが雑なので周囲のスタイルが崩れていたりしていろいろ弊害が出ていた。

改良版

なので少し修正をした。

a[role="link"]:not([rel]):not([aria-label]):only-of-type > [style] * {
  position: relative !important;
  padding-bottom: 0 !important;
  margin: 0 !important;
}
a[role="link"]:not([rel]):not([aria-label]):only-of-type > [style] img {
  opacity: 1 !important;
}

まあいろいろ手がかりとなるところを拾い出して無理やりセレクタを作ったのだがだいぶひどい感じになった。role="link"を当てにするのはいいとして、そこに not[rel]と not[aria-label]をつけている。これは role="link"の要素が画像以外にもいくつかあって、名前欄とか 「Show this thread」 とかも含まれる。で、それらには rel や aria-label がついていて画像の方には無いので除外してる。

:only-of-type というのは今回初めて知って使ったが、この type の要素が兄弟を持たないときにマッチする。なぜそうしているかというと、複数画像に対しては適用させたくないから。複数画像だとさらに親コンテナ側で比率固定していてそこは解除するのが難しいというか、解除するとレイアウトが壊れてしまうので無視したい。

複数画像は 2 枚、3 枚、4 枚のパターンがあり、2 枚のときは 要素が横並びに兄弟、4 枚では横並びのカラム内に 要素が縦に 2 枚ずつ兄弟になっているのでマッチしなくなる。ただ、3 枚の時は、1 つ目のカラムが 要素 1 枚だけなのでマッチしてしまう。

3 枚画像の 1 枚めだけ比率解除されてる例
3 枚画像の 1 枚めだけ比率解除されてる例

セレクタ作りしんどい

devTools で要素見ながらセレクタを探っていたが、なんか正規表現をテストできるサイトみたいに querySelector を GUI で動的にマッチ具合を見ながら構築できるサイトとかあったらいいのかもなと思った。