🚀 忙しい人向けまとめ
問題: VS CodeのClaude Codeチャット欄で日本語入力すると画面が左にずれまくる
解決法: VS Codeのデベロッパーツールで以下を実行
document.addEventListener('scroll',e=>e.target&&e.target.scrollLeft>0&&(e.target.scrollLeft=0),!0);
結果: 日本語入力時の画面ずれが完全解消!Event Captureフェーズでスクロールを即座にリセット
問題の発端とその技術的背景
VS CodeでClaude Code拡張機能を使ってると、チャット欄で日本語を入力する際に画面が左にずれて超使いづらい状況に遭遇しちゃいました。特に2画面環境だと、VS Codeが左側にあるときに変換候補ウィンドウが右画面に表示されるので、さらにずれが悪化。
普段使ってる別のターミナル環境やWSL接続では起こらないので、WindowsのVS Codeで日本語を使うときだけの現象。
技術的な原因の推測
この問題、おそらくIME(Input Method Editor)とWebviewの相互作用に起因してます。日本語入力時に以下のような処理が発生してる可能性が高いんです:
- IMEが起動して変換候補ウィンドウが表示される
- Webview内のテキストエリアが入力に応じて内部的にリサイズ
- リサイズに伴ってscrollLeftプロパティが変更される
- 結果として画面全体が左にずれる
これはもう何とかしないとダメだなって思って解決に乗り出してみました。
最初は複雑にやろうとしすぎた話(アンチパターン集)
1. CSS修正で何とかしようとした
当初は包括的なCSS修正で解決しようとして、フォント設定やIME制御、レンダリング最適化など、あれもこれもと複雑なスタイル修正を作成。
/* 最初の複雑すぎた修正案 */
input, textarea, div[contenteditable="true"] {
overflow-x: hidden !important;
word-wrap: break-word !important;
white-space: pre-wrap !important;
font-family: 'Consolas', 'MS Gothic', monospace !important;
ime-mode: active !important;
-webkit-overflow-scrolling: touch !important;
transform: translateZ(0) !important; /* GPUアクセラレーション */
will-change: transform !important;
/* ... 他にも大量の設定 */
}
でもこれ、根本的な解決にならなかったんですよね。なぜなら、問題はスタイリングではなく、JavaScriptレベルでのスクロール制御にあったから。
2. イベントハンドリングも追加してみた
CSS修正だけじゃ効果が薄かったから、IMEイベント(compositionstart、compositionend等)を監視する複雑なJavaScriptも追加。
// 複雑すぎたイベントハンドリング案
['compositionstart', 'compositionupdate', 'compositionend'].forEach(event => {
document.addEventListener(event, (e) => {
const target = e.target;
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
// スクロール位置を保存・復元する複雑なロジック
const scrollPos = { x: target.scrollLeft, y: target.scrollTop };
requestAnimationFrame(() => {
target.scrollLeft = scrollPos.x;
target.scrollTop = scrollPos.y;
});
}
});
});
でもこれらの方法だと根本的な解決には至らず。イベントの発火タイミングとスクロールの発生タイミングがずれてて、完全な制御ができなかったんです。
3. 根本原因を発見(デバッグプロセス)
問題をデバッグしてたら、実際の原因が水平スクロールの発生だってことが判明!以下のようなデバッグプロセスで特定しました:
// デバッグ用コード
const observer = new MutationObserver(() => {
console.log('DOM変更検出');
});
document.addEventListener('scroll', (e) => {
console.log('スクロールイベント:', {
target: e.target,
scrollLeft: e.target.scrollLeft,
scrollTop: e.target.scrollTop
});
}, true);
このデバッグで、日本語入力時にチャット欄が水平方向にスクロールしちゃって、それが画面のずれとして認識されてたことが分かりました。
最終的にたった1行で解決(エレガントな解決策)
結果的に、最もシンプルな1行のコードで問題が解決!
document.addEventListener('scroll',e=>e.target&&e.target.scrollLeft>0&&(e.target.scrollLeft=0),!0);
このコードの技術的詳細
document.addEventListener(
'scroll', // スクロールイベントを監視
e => { // イベントハンドラ
e.target && // nullチェック(防御的プログラミング)
e.target.scrollLeft > 0 && // 水平スクロールが発生してるか確認
(e.target.scrollLeft = 0) // 発生してたら即座にリセット
},
!0 // true = キャプチャフェーズで実行(重要!)
);
なぜこれが効果的なのか
- Event Captureフェーズでの処理: 第3引数に
true
を指定することで、イベントがDOM階層を下る段階(キャプチャフェーズ)で処理。これにより、他のイベントハンドラより先に実行される - 最小限のパフォーマンスインパクト: 単純な条件チェックと代入のみで、レンダリングへの影響を最小化
- 副作用の回避: 垂直スクロールには影響せず、水平スクロールのみをターゲットに
シンプルすぎて拍子抜けするレベル。でも、このシンプルさこそがエレガントなソリューションの証なんですよね。
自動化しようとして挫折した話(技術的制約の理解)
VS Code拡張機能のアーキテクチャの壁
VS Code拡張機能として自動化を試みたけど、以下のアーキテクチャ上の制約にぶつかりました:
// 拡張機能のコンテキスト(Node.js環境)
vscode.window.createWebviewPanel(...); // Webviewを作成
// Webview内(ブラウザ環境)
// ここでのみDOMアクセスが可能
// 拡張機能からは直接アクセスできない!
VS Code拡張機能はNode.js環境で動作するから、ブラウザのDOMオブジェクトに直接アクセスできないって制限があります。Claude CodeのチャットUIはWebview内で動作してるから、通常の拡張機能からは操作できないんですね。
Custom CSS and JS Loaderの限界
次にVS Codeの拡張機能であるCustom CSS and JS Loaderを使った完全自動化を試してみたけど:
// Custom CSS and JS Loaderの設定例
{
"vscode_custom_css.imports": [
"file:///path/to/custom.js"
]
}
Claude CodeのWebview環境は独立したサンドボックスとして動作してるため、グローバルなカスタマイズが適用されませんでした。これはセキュリティ的には正しい設計だけど、今回のケースでは障壁になっちゃいました。
バッチファイル自動化の複雑性
PowerShellとキーボード自動操作を組み合わせたバッチファイルによる自動化も検討:
# 複雑すぎた自動化案の一部
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
// ... 続く
}
"@
でも、ウィンドウハンドルの取得、キーストロークのシミュレーション、タイミング制御など、複雑すぎて実用的じゃないと判断して見送り。ROIが低すぎました。
結局シンプルな手動実行に落ち着いた(実用性重視)
最終的に、最もシンプルで確実な方法に落ち着きました:
実行手順
- VS Codeで
Help
→Toggle Developer Tools
を開く(Ctrl+Shift+I
) - Consoleタブを選択
- 以下のコードをコピペして実行:
document.addEventListener('scroll',e=>e.target&&e.target.scrollLeft>0&&(e.target.scrollLeft=0),!0);
実用性の観点から見た利点
- 永続性: VS Code起動時に一度だけ実行すれば、そのセッション中は効果が持続
- シンプルさ: コードは1行だから、スニペットとして保存しておけば瞬時に適用可能
- 確実性: 環境依存や権限問題を回避できる
- デバッグ容易性: 問題が発生してもConsoleで即座に確認可能
これで十分実用的だなって感じです。完璧を求めすぎて使いにくいツールを作るより、80%の問題を20%の労力で解決する方が賢明ですからね。
でも、めんどいので公式で解決して欲しいのが本音。