スクロールすると背景が途切れる！！！

# スクロールすると背景が途切れる！！！
この記事はCSSに関する知識記事なので、いきなりタイトル回収します。次のコードで説明します。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="wvPWEbV" data-user="tomolatoon" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/tomolatoon/pen/wvPWEbV">
  Untitled</a> by tomolatoon (<a href="https://codepen.io/tomolatoon">@tomolatoon</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

ローカルで試したい人は下のコードを見てください。

<details><summary>スクロールすると背景が途切れてしまうHTMLとCSS</summary><div>

```html:wrong.html
<!DOCTYPE HTML>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>ダメな例</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
<code class="codeblock">
<ol class="lines">
    <li class="line">'use strict';</li>
    <li class="line"> </li>
    <li class="line">// 幅を狭くしてスクロールしてみてください</li>
    <li class="line">`長くて枠をはみ出る文字列。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。`</li>
</ol>
</code>
</body>
</html>
```

```css:wrong.css
html {
    width: 100%;
    height: 100%;
    margin: 0;
    border: 0;

    font-size: 14px;
}

body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}

.codeblock {
    box-sizing: border-box;
    width: 100%;
    margin: 0;
    padding: 1rem;

    border-radius: 0.3rem;
    background-color: rgb(233, 233, 233);

    display: flex;
    flex-direction: column;
    overflow-x: auto;
}

.lines {
    box-sizing: border-box;
    width: 100%;
    margin: 0;
    padding: 0;
    padding-left: 35px;

    line-height: 1.5;
}

.line {
    width: 100%;
    margin: 0;
    padding: 0;

    white-space: pre;
}

.line:nth-of-type(even) {
    background-color: rgb(255, 255, 255);
}
```
</div></details>

## 症状
もうお分かりかと思いますが、`li`タグに書いてある文章が長くてオーバーフローした時、スクロールするとあった筈の背景色が途中で途切れてしまっています。これ、AtCoder社もやらかしていたりする（2022/2/4現在）のですが、少しCSSを追加すると直すことが出来ます。

## 原因と間違った解決策
もう見た目から自明なんですが、`li`タグの中身がオーバーフローしているのに、`li`タグへのスタイルは`width: 100%;`であるがゆえに適切な横幅を確保できていないのが原因です。
じゃあ`width: max-content;`とかにすればいいじゃんと思う人もいるかもしれませんが、それだと`li`タグの中身が少ない時に`width: 100%;`の場合よりも小さくなってしまいます。要するに行ごとの長さが揃って見えなくなります。

## 解決策
じゃあどうすればいいのかと言うと、`li`タグの`width: 100%;`を維持したまま、その親要素である`ol`タグに`width: 100%; min-width: max-content;`を適用します。ポイントは親要素には`width`と`min-width`を両方使うことですね。

### `ol`タグはどうなるかというと
こうすると、`ol`タグは子要素の幅のうち最大の幅をもつ子要素以上の大きさを持つことになります。かつ`ol`タグの親要素と同じ幅を持つので、画面サイズが大きくても小さくてもいい感じに背景部分が埋まるのがわかると思います。

### `li`タグたちはどうなるかというと
一方、`ol`タグの子要素である`li`タグたちの方は`width: 100%;`なので、`ol`タグと幅を揃えることになり、結果として兄弟関係にある`ol`タグのうち最大の幅を持つものに揃うわけなんですね。

## 結論のコード
結論のコードも貼っておきます。お好きな方をご利用ください。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="WNXxYQZ" data-user="tomolatoon" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/tomolatoon/pen/WNXxYQZ">
  Untitled</a> by tomolatoon (<a href="https://codepen.io/tomolatoon">@tomolatoon</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

<details><summary>解決したHTMLとCSS</summary><div>

```html:correct.html
<!DOCTYPE HTML>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>解決例</title>
    <link rel="stylesheet" href="correct.css">
</head>
<body>
<code class="codeblock">
<ol class="lines">
    <li class="line">'use strict';</li>
    <li class="line"> </li>
    <li class="line">// 幅を狭くしてスクロールしてみてください</li>
    <li class="line">`長くて枠をはみ出る文字列。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。`</li>
</ol>
</code>
</body>
</html>
```

```css:correct.css
html {
    width: 100%;
    height: 100%;
    margin: 0;
    border: 0;

    font-size: 14px;
}

body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}

.codeblock {
    box-sizing: border-box;
    width: 100%;
    margin: 0;
    padding: 1rem;

    border-radius: 0.3rem;
    background-color: rgb(233, 233, 233);

    display: flex;
    flex-direction: column;
    overflow-x: auto;
}

.lines {
    box-sizing: border-box;
    width: 100%;
    min-width: max-content;
    margin: 0;
    padding: 0;
    padding-left: 35px;

    line-height: 1.5;
}

.line {
    width: 100%;
    margin: 0;
    padding: 0;

    white-space: pre;
}

.line:nth-of-type(even) {
    background-color: rgb(255, 255, 255);
}
```
</div></details>

# あとがき
やっぱりCSSってパズル的な要素が強いですよね。コードブロックの実装を知りたい人や、背景が途切れてしまって解決策を知りたい人の助けになれば幸いです。（背景って書いちゃったけど、これ背景って言っていいのかな…）