넘친 내용으로 flexbox 스크롤


214

여기에 이미지 설명을 입력하십시오

위의 레이아웃을 달성하기 위해 사용 하는 코드는 다음과 같습니다 .

.header {
  height: 50px;
}

.body {
  position: absolute;
  top: 50px;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
}

.sidebar {
  width: 140px;
}

.main {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.content {
  flex: 1;
  display: flex;
}

.column {
  padding: 20px;
  border-right: 1px solid #999;
}
<div class="header">Main header</div>
<div class="body">
  <div class="sidebar">Sidebar</div>

  <div class="main">
    <div class="page-header">Page Header. Content columns are below.</div>
    <div class="content">
      <div class="column">Column 1</div>
      <div class="column">Column 1</div>
      <div class="column">Column 1</div>
    </div>
  </div>
</div>

스타일링에 사용 된 코드는 생략했습니다. 에서 모든 것을 볼 수 있습니다 .


위의 방법으로 작동하지만 content영역의 내용이 오버플로되면 전체 페이지가 스크롤됩니다. 콘텐츠 영역 자체 만 스크롤하기를 원하므로 div에 추가 overflow: auto했습니다content .

이 문제는 이제 열 자체가 부모 높이를 넘어 확장되지 않으므로 테두리도 잘립니다.

스크롤 문제를 보여주는 펜은 다음과 같습니다 .

content자식을 content상자 높이 이상으로 확장하면서 영역을 독립적으로 스크롤하도록 설정하는 방법은 무엇입니까?

답변:


264

나는 이것에 대해 Tab Atkins (flexbox spec의 저자)와 이야기했으며, 이것이 우리가 생각 해낸 것입니다.

HTML :

<div class="content">
    <div class="box">
        <div class="column">Column 1</div>
        <div class="column">Column 2</div>
        <div class="column">Column 3</div>
    </div>
</div>

CSS :

.content {
    flex: 1;
    display: flex;
    overflow: auto;
}

.box {
    display: flex;
    min-height: min-content; /* needs vendor prefixes */
}

펜은 다음과 같습니다.

  1. 짧은 열이 늘어나고 있습니다.
  2. 더 긴 열이 넘치고 스크롤 됩니다.

이것이 작동하는 이유 align-items: stretch는 고유 높이가 있으면 항목을 축소하지 않기 때문 min-content입니다.


3
부모의 키가 자녀에 의존하지 않을 때 작동합니다. 일반적으로 여기에 해당합니다. 최소 높이 : 100 %는 실제로 Firefox에서는 열이 짧을 때 문제를 해결합니다 (Chrome은 아니지만). Chrome 버그인지 Firefox 버그인지 확실하지 않습니다.
dholbert

1
@ dholbert-Tab Atkins가 도움이되었습니다. 내 답변을 업데이트했습니다.
Joseph Silber

3
Firefox는 현재 높이 값이 아닌 너비 값에 대해 "최소 콘텐츠"만 지원하므로 Firefox에서는 작동하지 않습니다. (예를 들어, 참조 bugzilla.mozilla.org/show_bug.cgi?id=852367 )
dholbert

2
@ dholbert-이 펜의 문제점은 공개되어 있으므로 누구나 변경할 수 있다는 것입니다. 그래서 여기 당신이 가고, 그 소유권을했다 : codepen.io/JosephSilber/pen/pmyHh
조셉 실버

5
예, 이것은 IE11에서 깨졌습니다
Steve

119

많은 시행 착오 끝에이 문제를 매우 우아하게 해결했습니다.

내 블로그 게시물을 확인하십시오 : http://geon.github.io/programming/2016/02/24/flexbox-full-page-web-app-layout

기본적으로 flexbox 셀을 스크롤 가능하게 만들려면 부모를 모두 만들어야합니다 overflow: hidden;. 그렇지 않으면 오버플로 설정을 무시하고 대신 부모를 더 크게 만듭니다.


11
이것은 내 경우에도 효과가 있었지만 와우, 그것이 작동 하는지에 대한 설명을 정말로보고 싶습니다 . 대부분의 경우 CSS 사양이 이런 종류의 도구에 대해 완전히 필연적이라는 것을 알았습니다.
markrian

2
귀하의 블로그 게시물에서 : "왜 그것이 효과가 있으며, 사양도 아무 것도 말하지 않습니다" . 그래서 왜 작동하는지에 대한 설명을 찾고 있습니다. 나는 사양을 훑어 보았지만 당신이 말한 것처럼 아무것도 뛰어 오르지 않습니다.
markrian

3
그것에 대해 좀 더 생각한 후에 말이됩니다. 기본 동작은 각 div가 모든 자식을 포함하도록 확장되는 것이므로 리프 노드에서 숨길 오버플로가 없습니다. DOM 상단에서 overflow : hidden을 강제로 숨겨야하므로 오버 플로우 및 스크롤하려는 노드까지 다운 될 때까지 부모가 자식을 수용 할 기회가 없습니다.
geon

3
나는 그것이 정말로 그것을 설명하고 있는지 확실하지 않습니다. 요소에서 오버플로를 숨김으로 설정해도 모든 하위 요소 인 AFAIK를 포함하도록 확장되지 않습니다. MDN에 따르면 : "오버플로 속성은 콘텐츠를 클립 수준으로 렌더링할지 스크롤 막대를 렌더링할지 아니면 콘텐츠가 블록 수준 컨테이너에 오버플로 될 때 콘텐츠를 표시할지 여부를 지정합니다." 또한 오버플로를 보이는 것 이외의 것으로 설정하면 새로운 블록 서식 컨텍스트가 만들어 지지만 플렉스 컨테이너는 이미 자체 블록 서식 컨텍스트를 만듭니다. developer.mozilla.org/en-US/docs/Web/Guide / CSS / ... .
markrian

1
나는 당신의 설명이 직관적 인 의미에 동의한다는 것을 덧붙여 야 하지만, 그것이 정확한 기술적 인 설명 이라고 생각하지 않습니다 . 그 이유를 진정으로 이해해야 만 미래에 해결책을 기억할 수있을 것입니다!
markrian

55

작업 position:absolute;과 함께 flex:

로 플렉스 아이템을 배치합니다 position: relative. 그런 다음 그 안에 다른 <div>요소를 추가하십시오 .

position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;

이것은 요소를 상대 위치 부모의 경계까지 확장하지만 확장 할 수는 없습니다. 내부 overflow: auto;는 예상대로 작동합니다.

  • 코드는 응답에 포함 된 스 니펫을 -을 클릭 여기에 이미지 설명을 입력하십시오하고 다음을 클릭 전체 페이지스 니펫을 실행 한 후 OR
  • 코덱을 보시려면 여기 를 클릭 하십시오
  • 결과: 여기에 이미지 설명을 입력하십시오

.all-0 {
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
p {
  text-align: justify;
}
.bottom-0 {
  bottom: 0;
}
.overflow-auto {
  overflow: auto;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet"/>


<div class="p-5 w-100">
  <div class="row bg-dark m-0">
    <div class="col-sm-9 p-0 d-flex flex-wrap">
      <!-- LEFT-SIDE - ROW-1 -->
      <div class="row m-0 p-0">
        <!-- CARD 1 -->
        <div class="col-md-8 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/700x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
        <!-- CARD 2 -->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
      </div>
      <div class="row m-0">
        <!-- CARD 3 -->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
        <!-- CARD 4 -->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
        <!-- CARD 5-->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
      </div>
    </div>
    <div class="col-sm-3 p-0">
      <div class="bg-white m-2 p-2 position-absolute all-0 d-flex flex-column">
        <h4>Social Sidebar...</h4>
        <hr />
        <div class="d-flex overflow-auto">
          <p>
            Topping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart.
            opping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart.
            opping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart.
            Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream
            chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate
            bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva
        </div>
      </div>
    </div>
  </div>

행운을 빕니다...


2
이 솔루션은 내부 구성 요소에 패딩 세트가있는 경우 특히 유용합니다. 원하는 위치에 잘 고정 될 수 있기 때문입니다. 훨씬 간단합니다. (네 box-sizing: border-box대신 설정할 수 있지만 특정 타사 컨트롤의 경우 더 복잡 할 수 있습니다).
Simon_Weaver

2
당신은 내 밤을 구 했어요!
Botea Florin

2
감사합니다. 어쨌든 나는 이것이 필요하다는 것에 실망했다. 그러나 나는 충고에 감사한다!
Mathias

9

조금 늦었지만 도움이 될 수 있습니다 : http://webdesign.tutsplus.com/tutorials/how-to-make-responsive-scrollable-panels-with-flexbox--cms-23269

기본적으로 당신은 둘 필요가 html, bodyheight: 100%; 와에 모든 콘텐츠를 감싸<div class="wrap"> <!-- content --> </div>

CSS :

html, body {
  height: 100%;
}

.wrap {
  height: 100vh;
  display: flex;
}

나를 위해 일했다. 그것이 도움이되기를 바랍니다.


"높이 : 100vh"를 사용할 때는 iOS Safari와 Android에서 다르게 측정되므로 매우주의해야합니다. 하나는 URL 막대의 높이를 고려하고 다른 하나는 URL 막대를 고려하지 않습니다.
Sean Anderson

7

이거 추가 해봐:

align-items: flex-start;

에 대한 규칙 .content {}. 그것은 적어도 (Firefox & Chrome 모두에서) 펜을 고정시킵니다.

기본적으로 .contenthas align-items: stretchhttp://dev.w3.org/csswg/css-flexbox/#algo-stretch 에 따라 모든 자동 높이 자식 크기를 자체 높이에 맞게 조정합니다 . 반대로, 값을 flex-start사용하면 어린이는 자신의 높이를 계산하고 시작 가장자리에 맞춰 정렬하고 오버플로하고 스크롤 막대를 트리거 할 수 있습니다.



또한 열의 높이가 더 이상 동일하지 않으므로 flexbox의 주요 매력 중 하나입니다.
Joseph Silber

확인. 그것이 디자인 제약이라는 것이 분명하지 않았습니다. 죄송합니다.
dholbert

대단한 제안
Vlad

1

내가 겪은 한 가지 문제는 요소에 스크롤 막대가 있어야 높이를 지정할 필요가 없다는 것입니다 (%는 아님).

요령은 각 열 내에 다른 div 세트를 중첩시키고 flex-direction : column으로 열 부모의 표시를 설정하는 것입니다.

    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
    }

    body {
        overflow-y: hidden;
        overflow-x: hidden;
        color: white;
    }

    .base-container {
        display: flex;
        flex: 1;
        flex-direction: column;
        width: 100%;
        height: 100%;
        overflow-y: hidden;
        align-items: stretch;
    }

    .title {
        flex: 0 0 50px;
        color: black;
    }

    .container {
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
    }

        .container .header {
            flex: 0 0 50px;
            background-color: red;
        }

        .container .body {
            flex: 1 1 auto;
            display: flex;
            flex-direction: row;
        }

            .container .body .left {
                display: flex;
                flex-direction: column;
                flex: 0 0 80px;
                background-color: blue;
            }
                .container .body .left .content,
                .container .body .main .content,
                .container .body .right .content {
                    flex: 1 1 auto;
                    overflow-y: auto;
                    height: 100px;
                }
                .container .body .main .content.noscrollbar {
                    overflow-y: hidden;
                }

            .container .body .main {
                display: flex;
                flex-direction: column;
                flex: 1 1 auto;
                background-color: green;
            }

            .container .body .right {
                display: flex;
                flex-direction: column;
                flex: 0 0 300px;
                background-color: yellow;
                color: black;
            }

    .test {
        margin: 5px 5px;
        border: 1px solid white;
        height: calc(100% - 10px);
    }
</style>

그리고 여기 html이 있습니다 :

<div class="base-container">
    <div class="title">
        Title
    </div>
    <div class="container">
        <div class="header">
            Header
        </div>
        <div class="body">
            <div class="left">
                <div class="content">
                    <ul>
                        <li>1</li>
                        <li>2</li>
                        <li>3</li>
                        <li>4</li>
                        <li>5</li>
                        <li>6</li>
                        <li>7</li>
                        <li>8</li>
                        <li>9</li>
                        <li>10</li>
                        <li>12</li>
                        <li>13</li>
                        <li>14</li>
                        <li>15</li>
                        <li>16</li>
                        <li>17</li>
                        <li>18</li>
                        <li>19</li>
                        <li>20</li>
                        <li>21</li>
                        <li>22</li>
                        <li>23</li>
                        <li>24</li>
                    </ul>
                </div>
            </div>
            <div class="main">
                <div class="content noscrollbar">
                    <div class="test">Test</div>
                </div>
            </div>
            <div class="right">
                <div class="content">
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>End</div>
                </div>
            </div>
        </div>
    </div>
</div>

https://jsfiddle.net/LiamFlavelle/czpjdfr4/


0

이 문제에 대한 해결책 overflow: auto;은 컨텐츠 래퍼를 스크롤 가능하게 만들기 위해 .content에 추가 하는 것입니다.

또한 Flexbox 래퍼 및 overflowed코드 펜 과 같은 스크롤 가능한 컨텐츠 와 함께 상황이 발생합니다. 합니다.

해결책은 overflow: hidden (or auto);큰 내용 주위에 랩퍼의 부모에 추가 하는 것입니다 (오버플로 : auto;로 설정).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.