7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Posted at

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

この記事はCSSに関する知識記事なので、いきなりタイトル回収します。次のコードで説明します。

See the Pen Untitled by tomolatoon (@tomolatoon) on CodePen.

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

スクロールすると背景が途切れてしまうHTMLとCSS
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>
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);
}

症状

もうお分かりかと思いますが、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;を適用します。ポイントは親要素にはwidthmin-widthを両方使うことですね。

olタグはどうなるかというと

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

liタグたちはどうなるかというと

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

結論のコード

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

See the Pen Untitled by tomolatoon (@tomolatoon) on CodePen.

解決したHTMLとCSS
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>
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);
}

あとがき

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

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?