• #css
  • #layout
  • #ui
  • #bug
開発misc-dev完了

行番号表示がコンテンツと重なる問題の調査と対応方針

問題の概要

DocPageコンポーネント (apps/web/app/components/DocPage.vue) において、モバイル表示時に --doc-line-gutter: 1rem に縮小すると、行番号がMarkdownコンテンツと重なってしまう。

発生した問題

  • 行番号の幅は 2.5rem 固定
  • モバイル対応で --doc-line-gutter: 1rem に縮小
  • 行番号がコンテンツ領域に 1.5rem 分はみ出して重なる

採用した解決策

モバイルでは行番号を非表示にし、デスクトップでは表示を維持

実装内容 (DocPage.vue:439-466)

.doc__body {
  --doc-line-gutter: 3rem;
  --doc-line-indent: 0rem;
  counter-reset: line-number;
  position: relative;
  padding-left: var(--doc-line-gutter);
}

/* モバイル: 行番号を非表示にして余白を削除 */
@media (max-width: 768px) {
  .doc__body {
    --doc-line-gutter: 0;
    padding-left: 1rem;
  }

  /* 行番号を非表示 */
  .doc__body :deep(h1)::before,
  .doc__body :deep(h2)::before,
  .doc__body :deep(h3)::before,
  .doc__body :deep(h4)::before,
  .doc__body :deep(h5)::before,
  .doc__body :deep(h6)::before,
  .doc__body :deep(p)::before,
  .doc__body :deep(pre)::before,
  .doc__body :deep(table)::before {
    display: none;
  }
}

効果

デスクトップ (769px以上):

  • padding-left: 3rem で行番号とコンテンツの間に十分な余白
  • 行番号が表示され、開発・デバッグ時に便利

モバイル (768px以下):

  • padding-left: 1rem でコンテンツ用の最小限の余白のみ
  • 行番号は非表示で、視覚的なノイズがない
  • 画面幅を有効活用できる

原因の調査

実装箇所

ファイル: apps/web/app/components/DocPage.vue:439-494

.doc__body {
  --doc-line-gutter: 1rem;  /* 行番号表示エリアの幅 (旧: 3rem) */
  --doc-line-indent: 0rem;
  counter-reset: line-number;
  position: relative;
  padding-left: var(--doc-line-gutter);
}

.doc__body :deep(h1),
.doc__body :deep(h2),
.doc__body :deep(h3),
.doc__body :deep(h4),
.doc__body :deep(h5),
.doc__body :deep(h6),
.doc__body :deep(p),
.doc__body :deep(pre),
.doc__body :deep(table) {
  counter-increment: line-number;
  position: relative;
}

.doc__body :deep(h1)::before,
.doc__body :deep(h2)::before,
.doc__body :deep(h3)::before,
.doc__body :deep(h4)::before,
.doc__body :deep(h5)::before,
.doc__body :deep(h6)::before {
  content: counter(line-number);
  position: absolute;
  left: calc(var(--doc-line-gutter) * -1 - var(--doc-line-indent, 0rem));
  top: 50%;
  transform: translateY(-50%);
  width: 2.5rem;
  text-align: right;
  font-size: 0.7rem;
  color: #9ca3af;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  user-select: none;
  pointer-events: none;
}

.doc__body :deep(p)::before,
.doc__body :deep(pre)::before,
.doc__body :deep(table)::before {
  content: counter(line-number);
  position: absolute;
  left: calc(var(--doc-line-gutter) * -1 - var(--doc-line-indent, 0rem));
  top: 0;
  width: 2.5rem;
  text-align: right;
  font-size: 0.7rem;
  color: #9ca3af;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  user-select: none;
  pointer-events: none;
}

問題の要因

  1. 行番号表示エリアの幅が不足
    • --doc-line-gutter: 1rem では、モバイル表示時に余白が少ない
    • 元々は 3rem だったが、レスポンシブ対応で 1rem に縮小
  2. 視覚的な区別が不明確
    • 行番号の色 (#9ca3af) がグレーで控えめではあるが、コンテンツとの境界が不明確
    • フォントサイズ (0.7rem) が小さく、見出しと近接すると混同しやすい
  3. モバイル環境での問題悪化
    • 画面幅が狭いため、1rem の余白では十分でない
    • padding-left: 1rem だけでは、行番号とコンテンツの間隔が不足

対応方針

方針1: 行番号表示機能の無効化 (推奨)

理由:

  • 行番号は主に開発者向けのデバッグ用途
  • 一般ユーザーにとっては不要であり、むしろ視覚的なノイズ
  • 無効化することで、レイアウトがシンプルになり、可読性が向上

実装:

/* DocPage.vue から行番号関連のCSSを削除 */
.doc__body {
  /* counter-reset: line-number; */ /* 削除 */
  position: relative;
  padding-left: 0; /* ガター不要 */
}

/* ::before 疑似要素による行番号表示をすべて削除 */

メリット:

  • コードがシンプルになる
  • パフォーマンスがわずかに向上 (疑似要素の削減)
  • 視覚的な混乱がなくなる

デメリット:

  • デバッグ時に行番号がないと、Markdown原稿とブラウザ表示の対応が分かりづらい

方針2: モバイル環境のみ無効化

レスポンシブ対応として、モバイル表示時のみ行番号を非表示にする。

実装:

.doc__body {
  --doc-line-gutter: 3rem;
  padding-left: var(--doc-line-gutter);
}

@media (max-width: 768px) {
  .doc__body {
    --doc-line-gutter: 0;
    padding-left: 0;
  }

  /* モバイルでは行番号を非表示 */
  .doc__body :deep(h1)::before,
  .doc__body :deep(h2)::before,
  .doc__body :deep(h3)::before,
  .doc__body :deep(h4)::before,
  .doc__body :deep(h5)::before,
  .doc__body :deep(h6)::before,
  .doc__body :deep(p)::before,
  .doc__body :deep(pre)::before,
  .doc__body :deep(table)::before {
    display: none;
  }
}

メリット:

  • デスクトップでは行番号が利用可能
  • モバイルでは視覚的な混乱を回避

デメリット:

  • メディアクエリが増え、CSSが複雑化
  • 一貫性が欠ける

方針3: 行番号のデザイン改善

行番号表示を維持しつつ、視覚的な干渉を軽減する。

実装:

.doc__body {
  --doc-line-gutter: 2rem; /* モバイルでも適度な余白 */
  padding-left: var(--doc-line-gutter);
}

.doc__body :deep(h1)::before,
.doc__body :deep(h2)::before,
/* ... */
{
  font-size: 0.6rem; /* さらに小さく */
  color: #d1d5db; /* より薄いグレー */
  opacity: 0.5; /* 半透明 */
}

@media (max-width: 768px) {
  .doc__body {
    --doc-line-gutter: 1.5rem; /* モバイルで少し縮小 */
  }
}

メリット:

  • 行番号機能を維持
  • 視覚的な干渉を軽減

デメリット:

  • 根本的な解決にはならない
  • 行番号が薄すぎて見づらくなる可能性

開発環境と本番環境の違いを検証する方法

もし開発環境での表示を確認したい場合は、以下の手順で本番ビルドをローカルで確認できます:

# 1. 本番ビルドを実行
cd apps/web
pnpm build

# 2. プレビューサーバーを起動
pnpm preview

# 3. ブラウザで http://localhost:4173 にアクセス

この方法で、本番環境と同じビルド結果をローカルで確認できます。

検証のポイント

  • 開発環境 (pnpm dev): HMRが有効、CSS変数が動的に適用
  • 本番環境 (pnpm build): CSS が最適化・マージされ、静的に配信される

参考情報