중첩 된 flexbox 레이아웃을 작업 중이며 다음과 같이 작동합니다.
가장 바깥 쪽 레벨 ( ul#main
)은 더 많은 항목이 추가 될 때 오른쪽으로 확장되어야하는 가로 목록입니다. 너무 커지면 가로 스크롤 막대가 있어야합니다.
#main {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
overflow-x: auto;
/* ...and more... */
}
이 목록 ( ul#main > li
) 의 각 항목 에는 헤더 ( ul#main > li > h2
)와 내부 목록 ( ul#main > li > ul.tasks
)이 있습니다. 이 내부 목록은 수직이므로 필요할 때 열로 줄 바꿈해야합니다. 더 많은 열을 감쌀 때 더 많은 항목을 넣을 공간을 만들기 위해 너비가 커져야합니다. 이 너비 증가는 외부 목록의 포함 항목에도 적용되어야합니다.
.tasks {
flex-direction: column;
flex-wrap: wrap;
/* ...and more... */
}
내 문제는 창의 높이가 너무 작아지면 내부 목록이 줄 바꿈되지 않는다는 것입니다. CSS-Tricks 의 지침을 꼼꼼하게 따르려고 노력하면서 모든 플렉스 속성을 많이 변경하려고 시도 했지만 운이 없습니다.
이 JSFiddle 은 지금까지 내가 가지고있는 것을 보여줍니다.
예상 결과 (내가 원하는 것) :
실제 결과 (내가 얻은 것) :
이전 결과 (2015 년에 얻은 것) :
최신 정보
약간의 조사가 끝나면 더 큰 문제처럼 보이기 시작합니다. 모든 주요 브라우저는 동일한 방식으로 작동하며 내 flexbox 디자인과 중첩되지 않습니다. 더 간단한 flexbox 열 레이아웃조차도 항목을 줄 바꿈 할 때 목록의 너비를 늘리지 않습니다.
이 다른 JSFiddle 은 문제를 분명히 보여줍니다. 현재 버전의 Chrome, Firefox 및 IE11에서는 모든 항목이 올바르게 줄 바꿈됩니다. 목록의 높이는 row
모드에서 증가 하지만 너비는 column
모드 에서 증가하지 않습니다 . 또한 column
모드 의 높이를 변경할 때 요소가 즉시 리플 로우되지 않지만 row
모드가 있습니다.
그러나 공식 사양 (특히 예 5 참조) 은 내가하고 싶은 일이 가능해야 함을 나타내는 것으로 보입니다.
누군가이 문제에 대한 해결 방법을 제안 할 수 있습니까?
업데이트 2
크기 조정 이벤트 중에 다양한 요소의 높이와 너비를 업데이트하기 위해 JavaScript를 사용하여 많은 실험을 한 후에는 너무 복잡하고 그렇게 해결하기가 너무 어렵다는 결론에 도달했습니다. 또한 JavaScript를 추가하면 flexbox 모델이 깨져서 최대한 깨끗하게 유지해야합니다.
지금 은 내부 컨테이너가 필요할 때 세로로 스크롤되도록 overflow-y: auto
대신에 넘어갑니다 flex-wrap: wrap
. 예쁘지는 않지만 최소한 사용성을 크게 손상시키지 않는 한 가지 방법입니다.
답변
문제
이것은 플렉스 레이아웃의 근본적인 결함처럼 보입니다.
열 방향의 플렉스 컨테이너는 추가 열을 수용하도록 확장되지 않습니다. (이 문제는 아닙니다 flex-direction: row
.)
이 질문은 CSS에서 명확한 대답없이 여러 번 요청되었습니다 (아래 목록 참조).
이 문제는 모든 주요 브라우저에서 발생하기 때문에 버그로 고정하기가 어렵습니다. 그러나 그것은 질문을 제기합니다 :
모든 주요 브라우저가 줄 방향으로 랩에서 열 방향이 아닌 플렉스 컨테이너를 확장 할 수 있습니까?
당신은 그들 중 적어도 하나가 그것을 올바르게 얻을 것이라고 생각할 것입니다. 나는 그 이유에 대해서만 추측 할 수 있습니다. 기술적으로 어려운 구현 일 수도 있고이 반복을 위해 보류 된 것일 수도 있습니다.
업데이트 : 이 문제는 Edge v16에서 해결 된 것으로 보입니다.
문제의 예
OP는 문제를 보여주는 유용한 데모를 만들었습니다. 여기에 복사하고 있습니다 : http://jsfiddle.net/nwccdwLw/1/
해결 방법 옵션
Stack Overflow 커뮤니티의 해키 솔루션 :
추가 분석
같은 문제를 설명하는 다른 게시물
- 플렉스 박스 컨테이너 너비가 커지지 않습니다
- 랩핑 된 내용물로 display : flex 컨테이너를 가로로 확장하려면 어떻게해야합니까?
- 플렉스 흐름 : 열 랩. 컨테이너 너비를 내용과 동일하게 설정하는 방법은 무엇입니까?
- 플렉스 박스 플렉스 플로우 열 랩 버그가 크롬에 있습니까?
- “flex-flow : column wrap”을 어떻게 사용합니까?
- 내용이 열로 줄 바꿈 될 때 Flex 컨테이너가 확장되지 않음
- flex-flow : 부모 컨테이너의 오버플로를 유발하는 flex 상자의 열 랩
- HTML flexbox 컨테이너가 래핑 된 자식 위로 확장되지 않습니다
- Flexbox 컨테이너와 넘친 Flex 어린이?
- 포장 된 품목에 맞게 신축성있는 Flexbox 용기를 만들려면 어떻게해야합니까?
- 여러 열이있을 때 하나의 열을 계산하는 Flex 컨테이너
- 플렉스로 컨테이너를 전체 너비로 만들기
- Flexbox 컨테이너 크기 조정이 가능합니까?
- 플렉스 랩 내부 플렉스 성장
- Flexbox는 성장
- flexbox 요소를 내용으로 확장 하시겠습니까?
- 내용에 맞게 flexbox 열 스트레치
- https://stackoverflow.com/q/48406237/3597276
- flex-flow : 열 줄 바꿈이 부모 요소의 너비를 늘리지 않습니다.
- 왜 <ul>이 모든 <li>를 포함하도록 너비를 확장하지 않습니까?
- Flexbox 열이 줄 바꿈 될 때 너비를 조정하는 방법은 무엇입니까?
- Flexbox 랩은 부모의 너비를 늘리지 않습니까?
답변
파티에 늦었지만 나중에이 문제가 계속 발생했습니다. 그리드를 사용하여 솔루션을 찾았습니다. 컨테이너에서 사용할 수 있습니다
display: grid;
grid-auto-flow: column;
grid-template-rows: repeat(6, auto);
FlexPen 문제와 그리드 수정 사이를 전환하는 CodePen의 예가 있습니다. https://codepen.io/MandeeD/pen/JVLdLd
답변
많은 주요 브라우저가 수년 후에이 버그로 고통받는 것은 유감입니다. 자바 스크립트 해결 방법을 고려하십시오. 브라우저 창의 크기가 조정되거나 컨텐츠가 요소에 추가 될 때마다이 코드를 실행하여 적절한 너비로 크기를 조정하십시오. 프레임 워크에서 지시문을 정의하여이를 수행 할 수 있습니다.
element.style.flexBasis = "auto";
element.style.flexBasis = `${element.scrollWidth}px`;
답변
방금 여기서 멋진 PURE CSS 해결 방법을 찾았습니다.
https://jsfiddle.net/gcob492x/3/
까다로운 : writing-mode: vertical-lr
목록 div에서 설정 한 다음 writing-mode: horizontal-tb
목록 항목에서 설정하십시오. JSFiddle에서 스타일을 조정해야했습니다 (솔루션에 필요하지 않은 많은 정렬 스타일을 제거하십시오).
참고 : 의견에 따르면 Firefox가 아닌 Chromium 기반 브라우저에서만 작동합니다. Chrome에서만 개인적으로 테스트했습니다. 다른 브라우저에서 작동하도록 수정하거나 다른 브라우저에서 작동하도록하는 방법이있을 수 있습니다.
이 의견에 대한 큰 소리 : flexbox 항목이 열 모드로 줄 바꿈되면 컨테이너의 너비가 커지지 않습니다 . 이 문제 스레드 를 파헤쳐 서 https://bugs.chromium.org/p/chromium/issues/detail?id=507397#c39로 연결되어이 JSFiddle로 연결되었습니다.
답변
해결책이나 적절한 해결 방법이 아직 제안되지 않았으므로 약간 다른 접근 방식으로 요청 된 동작을 얻을 수있었습니다. 레이아웃을 3 개의 다른 div로 분리하는 대신 모든 항목을 1 div에 추가하고 사이에 더 많은 div가있는 분리를 만듭니다.
제안 된 솔루션은 3 개의 섹션이 있다고 가정하지만 하드 코딩되어 있지만 일반적인 섹션으로 확장 될 수 있습니다. 주요 아이디어는이 레이아웃을 어떻게 달성 할 수 있는지 설명하는 것입니다.
- flex를 사용하여 항목을 감싸는 하나의 컨테이너 div에 모든 항목 추가
- 각 “내부 컨테이너”의 첫 번째 항목 (섹션이라고 함)에는 클래스가 있으며,이를 통해 각 섹션의 분리 및 스타일을 만드는 조작을 수행 할 수 있습니다.
:before
각 첫 번째 항목을 사용하여 각 섹션의 제목을 찾을 수 있습니다.- 를 사용
space
하면 섹션 사이에 간격이 생깁니다 - 는 이후
space
나는 또한 추가 해요 섹션의 전체 높이 포함되지 않습니다:after
절대 위치 및 흰색 배경으로 위치하도록 섹션을. - 각 섹션의 배경색을 스타일 지정하려면 각 섹션의 첫 번째 항목 안에 다른 div를 추가합니다. 나는 또한 절대적 입장을 가지고있을 것이다
z-index: -1
. - 각 배경의 올바른 너비를 얻으려면 JS를 사용하고 올바른 너비를 설정하고 크기를 조정할 리스너를 추가합니다.
function calcWidth() {
var size = $(document).width();
var end = $(".end").offset().left;
var todoWidth = $(".doing-first").offset().left;
$(".bg-todo").css("width", todoWidth);
var doingWidth = $(".done-first").offset().left - todoWidth;
$(".bg-doing").css("width", doingWidth);
var doneWidth = $(".end").offset().left - $(".done-first").offset().left;
$(".bg-done").css("width", doneWidth + 20);
}
calcWidth();
$(window).resize(function() {
calcWidth();
});
.container {
display: flex;
flex-wrap: wrap;
flex-direction: column;
height: 120px;
align-content: flex-start;
padding-top: 30px;
overflow-x: auto;
overflow-y: hidden;
}
.item {
width: 200px;
background-color: #e5e5e5;
border-radius: 5px;
height: 20px;
margin: 5px;
position: relative;
box-shadow: 1px 1px 5px 0px rgba(0, 0, 0, 0.75);
padding: 5px;
}
.space {
height: 150px;
width: 10px;
background-color: #fff;
margin: 10px;
}
.todo-first:before {
position: absolute;
top: -30px;
height: 30px;
content: "To Do (2)";
font-weight: bold;
}
.doing-first:before {
position: absolute;
top: -30px;
height: 30px;
content: "Doing (5)";
font-weight: bold;
}
.doing-first:after,
.done-first:after {
position: absolute;
top: -35px;
left: -25px;
width: 10px;
height: 180px;
z-index: 10;
background-color: #fff;
content: "";
}
.done-first:before {
position: absolute;
top: -30px;
height: 30px;
content: "Done (3)";
font-weight: bold;
}
.bg-todo {
position: absolute;
background-color: #FFEFD3;
width: 100vw;
height: 150px;
top: -30px;
left: -10px;
z-index: -1;
}
.bg-doing {
position: absolute;
background-color: #EFDCFF;
width: 100vw;
height: 150px;
top: -30px;
left: -15px;
z-index: -1;
}
.bg-done {
position: absolute;
background-color: #DCFFEE;
width: 10vw;
height: 150px;
top: -30px;
left: -15px;
z-index: -1;
}
.end {
height: 150px;
width: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="item todo-first">
<div class="bg-todo"></div>
Drink coffee
</div>
<div class="item">Go to work</div>
<div class="space"></div>
<div class="item doing-first">
<div class="bg-doing"></div>
1
</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="space"></div>
<div class="item done-first">
<div class="bg-done"></div>
1
</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="end"></div>
</div>
답변
가능한 JS 솔루션 ..
var ul = $("ul.ul-to-fix");
if(ul.find("li").length>{max_possible_rows)){
if(!ul.hasClass("width-calculated")){
ul.width(ul.find("li").eq(0).width()*ul.css("columns"));
ul.addClass("width-calculated");
}
}