X でテキスト主体のタイムラインを読みたいとき、画像や動画付きのツイートが続くと流れが分断されて読みづらい。 画像のみ表示の逆で、画像・動画付きのツイートを隠してテキストだけを残す方法をまとめる。 ブックマークレットですぐ試す方法と、ページを開くたびに自動で効く Chrome 拡張の2通りを用意した。

何ができるか

  • 画像・動画が含まれるツイートを自動で非表示
  • テキストのみのツイートだけが表示される
  • 読み物としてのタイムラインに集中できる
  • ワンクリックで ON/OFF 切り替え可能(拡張機能版)

方法1: ブックマークレット版

インストール不要で、ブックマークレットを作成するだけ。

  1. Chrome で新しいブックマークを作成(ブックマークバーを右クリック → 「ページを追加」)
  2. 名前を「Twitter テキストのみ」などに設定
  3. URL に以下のコードを貼り付け:
javascript:(function(){const id='twitter-text-only';let s=document.getElementById(id);if(s){s.remove();}else{s=document.createElement('style');s.id=id;s.textContent='div[data-testid="cellInnerDiv"]:has(article):has(div[data-testid="tweetPhoto"]),div[data-testid="cellInnerDiv"]:has(article):has(video){display:none!important;}';document.head.appendChild(s);}})();

使い方

  1. X(Twitter) のタイムラインを開く
  2. 作成したブックマークレットをクリック
  3. 画像・動画付きツイートが非表示になる
  4. もう一度クリックすると解除される(トグル動作)

方法2: Chrome 拡張機能版

ページを開くたびに自動で適用される拡張機能を作成する。

1. フォルダ構成

twitter-text-only-filter/
├── manifest.json
├── content.js
├── popup.html
└── popup.js

2. manifest.json

{
  "manifest_version": 3,
  "name": "Twitter Text Only Filter",
  "version": "1.0",
  "description": "X(Twitter)で画像・動画付きツイートを非表示にしてテキストのみ表示",
  "permissions": ["storage", "activeTab"],
  "content_scripts": [
    {
      "matches": ["https://x.com/*", "https://twitter.com/*"],
      "js": ["content.js"],
      "run_at": "document_end"
    }
  ],
  "action": {
    "default_popup": "popup.html"
  }
}

3. content.js

chrome.storage.sync.get(['enabled'], function(result) {
  if (result.enabled) applyFilter();
});

chrome.storage.onChanged.addListener(function(changes) {
  if (changes.enabled) {
    changes.enabled.newValue ? applyFilter() : removeFilter();
  }
});

function applyFilter() {
  const existing = document.getElementById('twitter-text-only-filter');
  if (existing) existing.remove();

  const style = document.createElement('style');
  style.id = 'twitter-text-only-filter';
  style.textContent = `
    div[data-testid="cellInnerDiv"]:has(article):has(div[data-testid="tweetPhoto"]),
    div[data-testid="cellInnerDiv"]:has(article):has(video) {
      display: none !important;
    }
  `;
  document.head.appendChild(style);
}

function removeFilter() {
  const style = document.getElementById('twitter-text-only-filter');
  if (style) style.remove();
}

4. popup.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    body { width: 200px; padding: 15px; font-family: sans-serif; }
    label { display: flex; align-items: center; cursor: pointer; }
    input[type="checkbox"] { margin-right: 8px; }
  </style>
</head>
<body>
  <label>
    <input type="checkbox" id="toggle">
    テキストのみ表示
  </label>
  <script src="popup.js"></script>
</body>
</html>

5. popup.js

const toggle = document.getElementById('toggle');
chrome.storage.sync.get(['enabled'], function(result) {
  toggle.checked = result.enabled || false;
});
toggle.addEventListener('change', function() {
  chrome.storage.sync.set({ enabled: toggle.checked });
});

6. 拡張機能のインストール

  1. Chrome で chrome://extensions/ を開く
  2. 右上の「デベロッパーモード」をオン
  3. 「パッケージ化されていない拡張機能を読み込む」をクリック
  4. 作成したフォルダを選択

仕組み

CSS の :has() 擬似クラスで、画像・動画を含むツイートを特定して非表示にしている。

  • div[data-testid="tweetPhoto"] を持つセル → 画像付きツイート
  • video 要素を持つセル → 動画付きツイート

ここでの肝は、:has() を使って「中に画像や動画を含むセル」を親側から指定しているところにある。以前の CSS は子要素の有無で親を選べなかったため、この種の絞り込みには JavaScript が必要だった。:has() が使えるようになったことで、要素をひとつ差し込むだけの短い CSS で済むようになった。ツイート1件は div[data-testid="cellInnerDiv"] という箱に入っていて、その箱の中に tweetPhotovideo があれば、箱ごと display: none で隠している。

投稿を削除するのではなく見えなくしているだけなので、解除すればすぐ元に戻る。スクロールで後から増えるツイートにも、CSS のルールが残っている限り自動で適用される。JavaScript で1件ずつ走査する方式と違い、新しく現れた要素を監視し続けなくてよい点が CSS で書く利点になる。

ブックマークレットと拡張機能の使い分け

ときどき切り替えたいだけならブックマークレットで足りる。クリックするとその場で効き、もう一度押すと戻る。ただしページをリロードしたり別のタイムラインに移ると解除される。常にテキストだけで読みたいなら拡張機能版にする。content script がページを開くたびに保存済みの設定を読み込むので、毎回ブックマークを押す手間がなくなる。まず動きを試したいときはブックマークレット、気に入って常用するなら拡張機能、という順で移ると無駄がない。

関連

逆の動き(画像・動画のみ表示)も同様の方法で実現できる。

よくある質問

画像だけ非表示にして、動画は残したい

セレクタから動画用の行を外せばいい。video を含む条件を削り、 div[data-testid="cellInnerDiv"]:has(article):has(div[data-testid="tweetPhoto"]) だけにすると、画像付きツイートだけが消えて動画はそのまま流れる。逆に動画だけ消したいなら tweetPhoto の行を外す。

スマホ(iPhone / Android アプリ)でも画像を非表示にできる?

ここで紹介したのはデスクトップの Chrome 向けで、スマホの X アプリには効かない。 iPhone なら Safari にブックマークレットを登録すれば Web 版のタイムラインで動かせる余地はあるが、 アプリ中心で見ている人が多いぶん、過度に期待しないほうがいい。PC で読むときの対策と割り切るのが現実的。

ミュートやブロックとは何が違う?

ミュートやブロックは相手単位で投稿を見えなくする機能で、X 側に状態が残る。 この方法は自分のブラウザの表示を変えるだけなので、特定の相手ではなく「画像・動画付き」という条件でまとめて隠せる。 相手の投稿そのものや通知には手を付けない。

つまずきやすいところ・注意

  • X 側の DOM は予告なく変わる。急に効かなくなったら、tweetPhotocellInnerDiv といったセレクタが今も合っているかを確認して直す。
  • ブックマークレット版はページをリロードすると解除される。常時効かせたいなら拡張機能版を使う。
  • :has() はやや新しめの CSS で、古いブラウザでは効かないことがある。最近の Chrome なら問題ない。
  • これは手元のタイムラインの見え方を変えるだけで、相手の投稿や通知には影響しない。