이 레이아웃을 달성하기위한 5 가지 옵션은 다음과 같습니다.
- CSS 포지셔닝
- 보이지 않는 DOM 요소가있는 Flexbox
- 보이지 않는 의사 요소가있는 Flexbox
- Flexbox
flex: 1
- CSS 그리드 레이아웃
방법 # 1 : CSS 포지셔닝 속성
position: relative
플렉스 용기에 바릅니다 .
position: absolute
항목 D에 적용하십시오 .
이제이 아이템은 플렉스 컨테이너 안에 절대적으로 위치합니다.
보다 구체적으로, 항목 D는 문서 플로우에서 제거되지만 가장 가까운 위치 조상 의 경계 내에 있습니다.
CSS의 오프셋 속성을 사용 top
하고 right
위치로이 요소를 이동합니다.
li:last-child {
position: absolute;
top: 0;
right: 0;
background: #ddd;
}
ul {
position: relative;
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p {
text-align: center;
margin-top: 0;
}
span {
background-color: aqua;
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
이 방법의 한 가지주의 사항 은 일부 브라우저는 정상 흐름에서 절대 위치 플렉스 항목을 완전히 제거하지 못할 수 있다는 것입니다. 이렇게하면 표준이 아닌 예기치 않은 방식으로 정렬이 변경됩니다. 자세한 내용 : IE11의 정상 흐름에서 절대적으로 배치 된 플렉스 항목이 제거되지 않음
방법 # 2 : 플렉스 자동 여백 및 보이지 않는 플렉스 아이템 (DOM 요소)
auto
여백 과 새로운 보이지 않는 플렉스 아이템의 조합으로 레이아웃을 달성 할 수 있습니다.
새 플렉스 항목은 항목 D와 동일하며 반대쪽 끝 (왼쪽 가장자리)에 배치됩니다.
보다 구체적으로, 플렉스 정렬은 여유 공간의 분포를 기반으로하기 때문에 새 항목은 세 개의 중간 상자를 가로로 가운데에 유지하는 데 필요한 균형을 맞 춥니 다. 새 항목은 기존 D 항목과 너비가 같아야합니다. 그렇지 않으면 가운데 상자가 정확하게 가운데에 배치되지 않습니다.
를 사용하여 새 항목이보기에서 제거됩니다 visibility: hidden
.
한마디로 :
D
요소 의 복제본을 작성하십시오 .
- 목록의 시작 부분에 배치하십시오.
- 사용은 플렉스
auto
유지하기 위해 마진을 A
, B
와 C
함께, 중심 D
요소가 양쪽에서 동일한 균형을 만들어.
visibility: hidden
복제본에 적용D
li:first-child {
margin-right: auto;
visibility: hidden;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>D</li><!-- new; invisible spacer item -->
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
방법 # 3 : 플렉스 자동 여백 및 보이지 않는 플렉스 항목 (의사 요소)
이 방법은 의미 적으로 더 깨끗하고 너비를 D
알아야한다는 점을 제외하고 # 2와 유사 합니다.
- 너비가 같은 의사 요소를 만듭니다
D
.
- 로 용기 시작 부분에로 놓습니다
::before
.
- 플렉스 사용
auto
유지하기 위해 마진을 A
, B
그리고 C
의사와 함께 완벽 중심 D
요소가 양쪽에서 동일한 균형을 만들어.
ul::before {
content:"D";
margin: 1px auto 1px 1px;
visibility: hidden;
padding: 5px;
background: #ddd;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
방법 # 4 : flex: 1
왼쪽 및 오른쪽 항목에 추가
위의 방법 # 2 또는 # 3으로 시작하여 왼쪽과 오른쪽 항목의 너비가 같아서 균형을 유지하는 대신 걱정하지 마십시오 flex: 1
. 이렇게하면 둘 다 사용 가능한 공간을 소비하여 중간 항목을 중앙에 배치합니다.
그런 다음 display: flex
컨텐츠를 맞추기 위해 개별 항목에 추가 할 수 있습니다 .
이 방법을 사용하는 방법에 대한 min-height
참고 사항 : 현재 Chrome, Firefox, Edge 및 기타 브라우저에서 단축 규칙flex: 1
은 다음과 같이 분류됩니다.
flex-grow: 1
flex-shrink: 1
flex-basis: 0%
즉 백분율 단위 (%) 에있는 flex-basis
경우의 원인이 방법 깰 min-height
용기에 사용된다. 일반적으로 자식의 백분율 높이 height
에는 부모 의 명시 적 속성 설정이 필요하기 때문 입니다.
이것은 1998 년으로 거슬러 올라간 오래된 CSS 규칙 ( CSS 레벨 2 )으로 많은 브라우저에서 어느 정도까지 유효합니다. 자세한 내용은 여기 및 여기를 참조 하십시오 .
다음은 user2651804 의 댓글에 게시 된 문제의 예입니다 .
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container>div {
background: orange;
margin: 5px;
}
#flex-container>div:first-child {
flex: 1;
}
#flex-container::after {
content: "";
flex: 1;
}
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
해결책은 백분율 단위를 사용하지 않는 것입니다. 시도 px
하거나 아무것도하지 마십시오 ( 적어도 주요 브라우저 중 일부는 어떤 이유로 든 백분율 단위를 추가 했음에도 불구하고 실제로 권장되는 사양입니다 ).
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container > div {
background: orange;
margin: 5px;
}
/* OVERRIDE THE BROWSER SETTING IN THE FLEX PROPERTY */
#flex-container > div:first-child {
flex: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex: 1;
flex-basis: 0;
}
/* OR... JUST SET THE LONG-HAND PROPERTIES INDIVIDUALLY
#flex-container > div:first-child {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
*/
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
방법 # 5 : CSS 그리드 레이아웃
가장 깨끗하고 효율적인 방법 일 수 있습니다. 절대 위치, 가짜 요소 또는 기타 해커가 필요하지 않습니다.
여러 개의 열이있는 그리드를 작성하기 만하면됩니다. 그런 다음 항목을 중간 및 끝 열에 배치하십시오. 기본적으로 첫 번째 열은 비워 두십시오.
ul {
display: grid;
grid-template-columns: 1fr repeat(3, auto) 1fr;
grid-column-gap: 5px;
justify-items: center;
}
li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }
/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p { text-align: center; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>| true center |</span></p>