플렉스 컨테이너를 가운데에 맞추고 플렉스 아이템을 왼쪽 정렬하는 방법


91

플렉스 항목이 중앙에 배치되기를 원하지만 두 번째 줄이있을 때 5 (아래 이미지에서)가 1 아래에 있고 부모의 중앙에 배치되지 않도록합니다.

여기에 이미지 설명 입력

내가 가지고있는 것의 예는 다음과 같습니다.

ul {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0;
  padding: 0;
}
li {
  list-style-type: none;
  border: 1px solid gray;
  margin: 15px;
  padding: 5px;
  width: 200px;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
</ul>

http://jsfiddle.net/8jqbjese/2/

답변:


79

Flexbox 당면 과제 및 한계

문제는 플렉스 아이템 그룹을 중앙에 놓고 랩에 왼쪽 정렬하는 것입니다. 그러나 행당 고정 된 수의 상자가 있고 각 상자가 고정 너비 인 경우를 제외하고는 현재 flexbox에서는 불가능합니다.

질문에 게시 코드를 사용하여, 우리는 현재 플렉스 용기 (랩하는 새로운 플렉스 컨테이너 만들 수 있습니다 ul우리가 중심을 허용 것) ul과를 justify-content: center.

그런 다음 플렉스 항목 ul 왼쪽 정렬 할 수 있습니다 justify-content: flex-start.

#container {
    display: flex;
    justify-content: center;
}

ul {
    display: flex;
    justify-content: flex-start;
}

이렇게하면 왼쪽으로 정렬 된 플렉스 항목의 중앙 그룹이 생성됩니다.

이 방법의 문제점은 특정 화면 크기에서의 오른쪽에 간격이 생겨 ul더 이상 중앙에 나타나지 않는다는 것입니다.

여기에 이미지 설명 입력 여기에 이미지 설명 입력

이것은 플렉스 레이아웃 (실제로는 일반적으로 CSS)에서 컨테이너가 다음과 같기 때문에 발생합니다.

  1. 요소가 언제 래핑되는지 알지 못합니다.
  2. 이전에 점유 한 공간이 현재 비어 있다는 것을 알지 못합니다.
  3. 더 좁은 레이아웃을 축소하기 위해 너비를 다시 계산하지 않습니다.

오른쪽에있는 공백의 최대 길이는 컨테이너가있을 것으로 예상했던 플렉스 항목의 길이입니다.

다음 데모에서 창 크기를 가로로 조정하면 공백이왔다 갔다하는 것을 볼 수 있습니다.

데모


보다 실용적인 접근

Flexbox inline-block미디어 쿼리를 사용하지 않고도 원하는 레이아웃을 얻을 수 있습니다. .

HTML

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
</ul>

CSS

ul {
    margin: 0 auto;                  /* center container */
    width: 1200px;
    padding-left: 0;                 /* remove list padding */
    font-size: 0;                    /* remove inline-block white space;
                                        see https://stackoverflow.com/a/32801275/3597276 */
}

li {
    display: inline-block;
    font-size: 18px;                 /* restore font size removed in container */
    list-style-type: none;
    width: 150px;
    height: 50px;
    line-height: 50px;
    margin: 15px 25px;
    box-sizing: border-box;
    text-align: center;
}

@media screen and (max-width: 430px) { ul { width: 200px; } }
@media screen and (min-width: 431px) and (max-width: 630px) { ul { width: 400px; } }
@media screen and (min-width: 631px) and (max-width: 830px) { ul { width:600px;  } }
@media screen and (min-width: 831px) and (max-width: 1030px) { ul { width: 800px; } }
@media screen and (min-width: 1031px) and (max-width: 1230px) { ul { width: 1000px; } }

위의 코드는 다음과 같이 왼쪽 정렬 된 자식 요소가있는 수평 중앙 컨테이너를 렌더링합니다.

여기에 이미지 설명 입력

데모


다른 옵션


3
네, 사람들이하고 싶어하고 결국 flexbox를 사용하는 많은 것은 실제로 그리드를 만드는 것입니다. 운 좋게도 CSS 그리드가 더 완성 된 상태에 도달하면이를 다룰 것입니다.
TylerH

1
이 게시물 을 귀하의 게시물 에 연결 했습니다 . 동일한 문제를 해결하는 방법이 하나 더 있지만 여전히 속일 수 있으므로 살펴보고 닫을 것인지 직접 결정하십시오. 그리고 이것에 대한 훌륭한 설명을 위해 1을 더하십시오.
Ason

아마도 또 다른 아이디어는 margin:0 auto모든 것이 페이지의 중앙에 있도록 부모 래퍼에서 수행하는 것입니다. 그 시점부터 모든 하위 구성 요소 (즉, 첫 번째 플렉스 컨테이너)는 정상적인 흐름 행 프로세스로 진행됩니다. 이것은 간단하게 만들 수있는 것 같습니다.
klewis

12

CSS Grid로 달성 할 수 있습니다. repeat(autofit, minmax(width-of-the-element, max-content))

ul {
       display: grid;
       grid-template-columns: repeat(auto-fit, minmax(210px, max-content));
       grid-gap: 16px;
       justify-content: center;
       padding: initial;
}

li {
    list-style-type: none;
    border: 1px solid gray;
    padding: 5px;
    width: 210px;
}
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
</ul>

http://jsfiddle.net/rwa20jkh/


흥미 롭군. 그러나 그리드의 오른쪽 또는 중앙에있는 간격을 제거하지는 않습니다
Red

2
@Red 한 가지 잘못되었습니다. 나는 변화 justify-items: centerjustify-content:center, 지금은 완벽 센터.
Joe82

210px내부 부분을 이해하지 못합니다 minmax. 어떻게 동일하지만 인위적인 제한없이 어떻게합니까 210px? flexbox에는 이러한 제한이 없습니다. flexbox와 똑같은 결과를 원하지만 콘텐츠 영역은 솔루션과 같이 중앙에 있어야합니다.
Andrey Mikhaylov-lolmaus

1
안녕하세요 @ AndreyMikhaylov-lolmaus,이 방법은 모든 요소에 고정 너비를 설정하려는 경우에 작동합니다. 질문에서는로 표현됩니다 width:200px. 제 예에서는 제가 설정 width:210pxminmax
한대로이

@ Joe82 명확히 해주셔서 감사합니다! 🙏 임의의 너비 요소에 대해 작동하는 방법을 알고 있습니까?
Andrey Mikhaylov-lolmaus

0

@michael이 제안했듯이 이것은 현재 flexbox의 제한 사항입니다. 그러나 여전히 flexand를 사용하려면 justify-content: center;더미 li요소 를 추가하고을 할당 하여이 문제를 해결할 수 있습니다 margin-left.

    const handleResize = () => {
        const item_box = document.getElementById('parentId')
        const list_length  = item_box.clientWidth
        const product_card_length = 200 // length of your child element
        const item_in_a_row = Math.round(list_length/product_card_length)
        const to_be_added = item_in_a_row - parseInt(listObject.length % item_in_a_row) // listObject is the total number items
        const left_to_set = (to_be_added - 1 ) * product_card_length // -1 : dummy item has width set, so exclude it when calculating the left margin 
        const dummy_product = document.querySelectorAll('.product-card.dummy')[0]
        dummy_product.style.marginLeft = `${left_to_set}px`
    }
    handleResize() // Call it first time component mount
    window.addEventListener("resize", handleResize); 

참고로이 바이올린 (크기 조정 및 참조) 또는 비디오를 확인하십시오.


0

여백이있는 원하는 스타일을 얻는 한 가지 방법은 다음을 수행하는 것입니다.

#container {
    display: flex;
    justify-content: center;
}

#innercontainer {
    display: flex;
    flex: 0.9; -> add desired % of margin
    justify-content: flex-start;
}

0

다른 클래스와 동일한 클래스 (전람 목적을 위해 예에서 제거됨) 및 높이가 0으로 설정된 보이지 않는 요소를 배치 할 수 있습니다.이를 통해 항목을 그리드의 맨 처음에 맞출 수 있습니다.

<div class="table-container">
  <div class="table-content">
    <p class="table-title">Table 1</p>
    <p class="mesa-price">$ 20</p>
  </div>
  
  <!-- Make stuff justified start -->
  <div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
  <div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
  <div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
  <div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
</div>

결과

여기에 이미지 설명 입력


-1

React Native로 코딩하는 동안이 문제가 발생했습니다. FlexBox를 사용하여 가질 수있는 우아한 솔루션이 있습니다. 내 특정 상황에서는 alignItems를 사용하여 세 개의 플렉스 상자 (Flex : 2)를 다른 상자 안에 가운데에 배치하려고했습니다. 내가 생각 해낸 해결책은 각각 Flex와 함께 두 개의 빈을 사용하는 것입니다.

<View style={{alignItems: 'center', flexWrap: 'wrap', flexDirection: 'row'}}>
  <View style={{flex: 1}} />
    // Content here
  <View style={{flex: 1}} />
</View>

웹 / CSS로 쉽게 변환 할 수 있습니다.


당신은 질문을 오해했습니다. OP는 3 개 항목을 중앙에 배치하는 방법을 묻지 않고, 모든 항목이 그룹으로 중앙에있는 동안 두 번째 행에 항목을 왼쪽 정렬하는 방법을 묻고 솔루션이 작동하지 않습니다.
Ason
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.