programing

CSS 전용 조적 배치

closeapi 2023. 9. 13. 22:37
반응형

CSS 전용 조적 배치

조적 배치를 구현해야 합니다.하지만 여러 가지 이유로 자바스크립트를 사용하고 싶지 않습니다.

A grid of multiple columns of rectangles of varying height.

매개변수:

  • 모든 요소의 너비가 동일합니다.
  • 요소는 서버측을 계산할 수 없는 높이를 갖습니다(이미지에 다양한 텍스트 양을 더한 값)
  • 필요하다면 나는 고정된 수의 열을 가지고 살 수 있습니다.

현대 브라우저, 속성에서 작동하는 사소한 해결책이 있습니다.

이 솔루션의 문제점은 요소가 열로 정렬된다는 것입니다.

Starting from the top leftmost box, they're numbered 1 through 4 straight down, the topmost box in the next column is 5, and so on.

저는 요소들을 줄을 지어 순서를 정해야 하지만, 적어도 대략 다음과 같습니다.

Starting from the top leftmost box, they're numbered 1 through 6 straight across, but because box 5 is the shortest the box underneath it is 7 as it has the appearance of being on a row higher than the next box on the far left.

시도해 본 접근 방식은 효과가 없습니다.

이제 서버 측 렌더링을 변경하고 항목 수를 열 수로 나누는 항목을 다시 정렬할 수 있지만 복잡하고 오류가 발생하기 쉬우므로(브라우저가 항목 목록을 열로 나누는 방법에 따라) 가능하면 피하고 싶습니다.

이것을 가능하게 하는 플렉스박스 마법이 있습니까?

2021년 업데이트

Layout 에는 CSS 을 3 합니다 합니다 을 masonry특징.

코드는 다음과 같습니다.

grid-template-rows: masonry
grid-template-columns: masonry

2021년 3월 현재 파이어폭스에서만 사용할 수 있습니다(플래그 활성화 후).

업데이트 종료; 아래의 원래 답변


플렉스박스

flexbox의 경우 동적 조적 배치는 적어도 깨끗하고 효율적인 방법으로는 불가능합니다.

Flexbox는 1차원 레이아웃 시스템입니다.즉, 수평 또는 수직 선을 따라 항목을 정렬할 수 있습니다.플렉스 항목은 해당 행 또는 열에 제한됩니다.

실제 그리드 시스템은 2차원으로, 수평 및 수직 선을 따라 항목을 정렬할 수 있습니다.내용 항목은 행과 열에 동시에 걸쳐 있을 수 있지만 플렉스 항목은 할 수 없습니다.

이것이 플렉스박스가 그리드를 구축할 수 있는 용량이 제한적인 이유입니다.W3C가 또 다른 CSS3 기술인 그리드 레이아웃을 개발한 이유이기도 합니다.


row wrap

에 에 에 flex-flow: row wrap, 플렉스 항목은 행으로 래핑해야 합니다.

, 플렉스 항목은 같은 행의 다른 항목 아래에 래핑할없습니다.

div #3 div #1 아래를 어떻게 감싸서 새로운 행을 만드는지 위에서 주목하세요.div #2 아래로는 랩할 수 없습니다.

따라서 항목이 열에서 가장 높지 않은 경우 공백이 남아 보기 흉한 간격이 발생합니다.


column wrap

flex-flow: column wrap 구현될 수 즉, 와 이 합니다 합니다 이 와 .그러나 열 방향 컨테이너는 바로 다음과 같은 네 가지 잠재적 문제를 가지고 있습니다.

  1. 플렉스 항목은 수평이 아닌 수직으로 흐릅니다(이 경우 필요한 것처럼).
  2. 컨테이너는 핀터레스트 레이아웃과 같이 수직이 아닌 수평으로 확장됩니다.
  3. 컨테이너의 높이가 정해져 있어야 하기 때문에 물건들은 포장 위치를 알고 있습니다.
  4. 이 글을 쓰는 현재 모든 주요 브라우저에서 추가 열을 수용하기 위해 컨테이너가 확장되지 않는 결함이 있습니다.

결과적으로 열 방향 컨테이너는 이 경우와 다른 많은 경우에 선택 사항이 아닙니다.


항목 치수가 정의되지 않은 CSS 그리드

콘텐츠 항목의 다양한 높이를 미리 결정할 수 있다면 그리드 레이아웃이 문제 해결에 완벽한 방법이 될 것입니다.다른 모든 요구 사항은 그리드의 용량 내에 있습니다.

주변 항목과의 간격을 좁히려면 그리드 항목의 너비와 높이를 알아야 합니다.

따라서 수평으로 흐르는 석조 레이아웃을 구축하기 위해 제공해야 하는 최고의 CSS인 그리드는 이 경우 부족합니다.

실제로 CSS 기술이 자동으로 틈을 좁히는 기능을 갖춘 상태로 도달하기 전까지는 일반적으로 CSS는 해결책이 없습니다.이와 같은 경우 문서를 다시 확인해야 할 것이므로 얼마나 유용하거나 효율적인지 잘 모르겠습니다.

대본이 필요할 겁니다.

자바스크립트 솔루션은 문서 흐름에서 내용 항목을 제거하여 공백 없이 다시 정렬하는 절대 포지셔닝을 사용하는 경향이 있습니다.다음은 두 가지 예입니다.

Masonry는 자바스크립트 그리드 레이아웃 라이브러리입니다.벽에 있는 석공 피팅 스톤과 같이 사용 가능한 수직 공간을 기준으로 요소를 최적의 위치에 배치하여 작동합니다.

출처 : http://masonry.desandro.com/

[핀터레스트] 정말 멋진 사이트입니다. 하지만 흥미로운 것은 이 핀보드들이 어떻게 배치되느냐는 것입니다.그래서 이 자습서의 목적은 이 반응형 블록 효과를 우리 스스로 다시 만드는 것입니다.

출처 : https://benholland.me/javascript/2012/02/20/how-to-build-a-site-that-works-like-pinterest.html


항목 치수가 정의된 CSS 그리드

콘텐츠 항목의 너비와 높이를 알 수 있는 레이아웃의 경우 순수 CSS에서 수평으로 흐르는 조적 레이아웃이 다음과 같습니다.

grid-container {
  display: grid;                                                /* 1 */
  grid-auto-rows: 50px;                                         /* 2 */
  grid-gap: 10px;                                               /* 3 */
  grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));   /* 4 */
}

[short] {
  grid-row: span 1;                                             /* 5 */
  background-color: green;
}

[tall] {
  grid-row: span 2;
  background-color: crimson;
}

[taller] {
  grid-row: span 3;
  background-color: blue;
}

[tallest] {
  grid-row: span 4;
  background-color: gray;
}

grid-item {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3em;
  font-weight: bold;
  color: white;
}
<grid-container>
  <grid-item short>01</grid-item>
  <grid-item short>02</grid-item>
  <grid-item tall>03</grid-item>
  <grid-item tall>04</grid-item>
  <grid-item short>05</grid-item>
  <grid-item taller>06</grid-item>
  <grid-item short>07</grid-item>
  <grid-item tallest>08</grid-item>
  <grid-item tall>09</grid-item>
  <grid-item short>10</grid-item>
  <grid-item tallest>etc.</grid-item>
  <grid-item tall></grid-item>
  <grid-item taller></grid-item>
  <grid-item short></grid-item>
  <grid-item short></grid-item>
  <grid-item short></grid-item>
  <grid-item short></grid-item>
  <grid-item tall></grid-item>
  <grid-item short></grid-item>
  <grid-item taller></grid-item>
  <grid-item short></grid-item>
  <grid-item tall></grid-item>
  <grid-item short></grid-item>
  <grid-item tall></grid-item>
  <grid-item short></grid-item>
  <grid-item short></grid-item>
  <grid-item tallest></grid-item>
  <grid-item taller></grid-item>
  <grid-item short></grid-item>
  <grid-item tallest></grid-item>
  <grid-item tall></grid-item>
  <grid-item short></grid-item>
</grid-container>

jsFiddle 데모


작동 원리

  1. 블록 레벨 그리드 컨테이너를 설정합니다. (inline-grid다른 옵션이 될 것입니다.)

  2. 이 속성은 자동으로 생성된 행의 높이를 설정합니다.이 그리드에서 각 행의 높이는 50px입니다.

  3. 그 부동산은 의 줄임말입니다.grid-column-gap그리고.grid-row-gap. 이 규칙은 그리드 항목 사이에 10px 간격을 설정합니다.(품목과 용기 사이의 부위에는 해당되지 않습니다.)

  4. 속성은 명시적으로 정의된 열의 너비를 설정합니다.

    표기법은 반복되는 열(또는 행)의 패턴을 정의합니다.

    이 함수는 그리드에 컨테이너를 넘치지 않고 가능한 한 많은 열(또는 행)을 정렬하도록 지시합니다.(이것은 플렉스 레이아웃과 유사한 동작을 만들 수 있습니다.flex-wrap: wrap.)

    함수는 각 열(또는 행)에 대해 최소 및 최대 크기 범위를 설정합니다.위의 코드에서 각 열의 너비는 컨테이너의 최소 30%이며 사용 가능한 여유 공간의 최대입니다.

    장치는 그리드 컨테이너의 여유 공간의 일부분을 나타냅니다.플렉스박스와 비교해도 손색이 없습니다.flex-grow소유물.

  5. 그리고 그리드 항목에 몇 줄을 넘어야 하는지를 알려주고 있습니다.

flexbox: https://tobiasahlin.com/blog/masonry-with-css/ 와 관련된 최근 발견된 기술입니다.

기사는 저에게 이해가 되지만, 사용해 본 적이 없어서 마이클의 답변에 언급된 것 외에 주의할 점이 있는지 모르겠습니다.

여기에서 를 .order,를과 :nth-child.

스택 스니펫

.container {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  /* Your container needs a fixed height, and it 
   * needs to be taller than your tallest column. */
  height: 960px;
  
  /* Optional */
  background-color: #f7f7f7;
  border-radius: 3px;
  padding: 20px;
  width: 60%;
  margin: 40px auto;
  counter-reset: items;
}

.item {
  width: 24%;
  /* Optional */
  position: relative;
  margin-bottom: 2%;
  border-radius: 3px;
  background-color: #a1cbfa;
  border: 1px solid #4290e2;
  box-shadow: 0 2px 2px rgba(0,90,250,0.05),
    0 4px 4px rgba(0,90,250,0.05),
    0 8px 8px rgba(0,90,250,0.05),
    0 16px 16px rgba(0,90,250,0.05);
  color: #fff;
  padding: 15px;
  box-sizing: border-box;
}

 /* Just to print out numbers */
div.item::before {
  counter-increment: items;
  content: counter(items);
}

/* Re-order items into 3 rows */
.item:nth-of-type(4n+1) { order: 1; }
.item:nth-of-type(4n+2) { order: 2; }
.item:nth-of-type(4n+3) { order: 3; }
.item:nth-of-type(4n)   { order: 4; }

/* Force new columns */
.break {
  flex-basis: 100%;
  width: 0;
  border: 1px solid #ddd;
  margin: 0;
  content: "";
  padding: 0;
}

body { font-family: sans-serif; }
h3 { text-align: center; }
<div class="container">
  <div class="item" style="height: 140px"></div>
  <div class="item" style="height: 190px"></div>
  <div class="item" style="height: 170px"></div>
  <div class="item" style="height: 120px"></div>
  <div class="item" style="height: 160px"></div>
  <div class="item" style="height: 180px"></div>
  <div class="item" style="height: 140px"></div>
  <div class="item" style="height: 150px"></div>
  <div class="item" style="height: 170px"></div>
  <div class="item" style="height: 170px"></div>
  <div class="item" style="height: 140px"></div>
  <div class="item" style="height: 190px"></div>
  <div class="item" style="height: 170px"></div>
  <div class="item" style="height: 120px"></div>
  <div class="item" style="height: 160px"></div>
  <div class="item" style="height: 180px"></div>
  <div class="item" style="height: 140px"></div>
  <div class="item" style="height: 150px"></div>
  <div class="item" style="height: 170px"></div>
  <div class="item" style="height: 170px"></div>
  
  <span class="item break"></span>
  <span class="item break"></span>
  <span class="item break"></span>
</div>

나는 이 해결책을 찾았는데, 아마도 모든 브라우저와 호환될 것입니다.

참고: 오류 또는 브라우저 지원 문제가 발견된 경우.이 답변을 업데이트하거나 댓글을 달아주세요.

CSS 속성 지원 참조:

수, 간격, 채우기 구분 기호, 페이지 구분 기호

:page-break-inside으로로 되었습니다.break-inside소유물.

  

.container {
  -moz-column-count: 1;
       column-count: 1;
  -moz-column-gap: 20px;
       column-gap: 20px;
  -moz-column-fill: balance;
       column-fill: balance;
  margin: 20px auto 0;
  padding: 2rem;
}
.container .item {
  display: inline-block;
  margin: 0 0 20px;
  page-break-inside: avoid;
  -moz-column-break-inside: avoid;
       break-inside: avoid;
  width: 100%;
}
.container .item img {
  width: 100%;
  height: auto;
}
@media (min-width: 600px) {
  .container {
    -moz-column-count: 2;
         column-count: 2;
  }
}
@media (min-width: 900px) {
  .container {
    -moz-column-count: 3;
         column-count: 3;
  }
}
@media (min-width: 1200px) {
  .container {
    -moz-column-count: 4;
         column-count: 4;
  }
}
   
 CSS-Only Masonry Layout 
  
<div class="container">
  <div class="item"><img src="https://placeimg.com/600/400/animals" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/600/arch" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/300/nature" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/450/people" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/350/tech" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/800/animals/grayscale" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/650/arch/sepia" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/300/nature/grayscale" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/400/people/sepia" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/600/tech/grayscale" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/200/animals/sepia" alt=""></div>
  <div class="item"><img src="https://placeimg.com/600/700/arch/grayscale" alt=""></div>
</div>

마지막으로 쉽게 조적 배치를 만들 수 있는 CSS 전용 솔루션이지만 현재로서는 지원이 없기 때문에 인내심을 가져야 합니다.

이 기능은 CSS 그리드 레이아웃 모듈 레벨 3에 도입되었습니다.

본 모듈에서는 CSS Grid 컨테이너의 추가 레이아웃 모드로 조적 레이아웃을 소개합니다.

그리고나서

축 중 하나에 대한 값 조적조를 지정하여 조적조 레이아웃을 그리드 컨테이너에서 지원합니다.이 축을 조적 축이라고 하고 다른 축을 그리드 축이라고 합니다.

기본적인 예는 다음과 같습니다.

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-template-rows: masonry; /* this will do the magic */
  grid-gap: 10px;
}

img {
  width: 100%;
}
<div class="container">
  <img src="https://picsum.photos/id/1/200/300">
  <img src="https://picsum.photos/id/17/200/400">
  <img src="https://picsum.photos/id/18/200/100">
  <img src="https://picsum.photos/id/107/200/200">
  <img src="https://picsum.photos/id/1069/200/600">
  <img src="https://picsum.photos/id/12/200/200">
  <img src="https://picsum.photos/id/130/200/100">
  <img src="https://picsum.photos/id/203/200/100">
  <img src="https://picsum.photos/id/109/200/200">
  <img src="https://picsum.photos/id/11/200/100">
</div>

여기에 설명된 것과 같은 기능을 활성화하면 Firefox에서 다음과 같은 결과가 나타납니다. https://caniuse.com/ ?search=firstry.

  1. Firefox를 열고 url bar에 about:config를 씁니다.
  2. 석공으로 수색을 하다
  3. 당신은 하나의 깃발을 얻을 것이고, 진실을 만들 것입니다.

CSS masonry layout

화면을 줄이면 반응이 좋은 부분이 완벽해요!

Masonry layout using CSS only

CSS를 사용하는 응답 방식이 여기 있습니다.columns.
참고: 요소는 행이 아닌 열로 정렬됩니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
    <title>Responsive Grid Layout</title>
</head>
<body>
    <div class="wrapper">
        <div class="box box1">Content of box 1</div>
        <div class="box box2">Content of box 2</div>
        <div class="box box3">Content of box 3</div>
        <div class="box box4">Content of box 4</div>
        <div class="box box5">Content of box 5</div>
        <div class="box box6">Content of box 6</div>
        <div class="box box7">Content of box 7</div>
    </div>
</body>
</html>
body {
    margin: 0;
    display: flex;
    justify-content: center;
}

.wrapper {
  column-count: auto;
  column-width: 320px; /* 300px + 20px gap */
  column-gap: 20px;
  width: 100%;
  max-width: 1000px;
  padding: 20px;
  box-sizing: border-box;
}

.box {
  background-color: lightblue;
  border: 1px solid blue;
  padding: 20px;
  font-size: 1.5em;
  text-align: center;
  width: 300px;
  box-sizing: border-box;
  display: inline-block;
  margin-bottom: 20px;
  break-inside: avoid-column;
}

.box1 {
  height: 800px;
}
.box2 {
  height: 300px;
}
.box3 {
  height: 300px;
}
.box4 {
  height: 300px;
}

enter image description here

언급URL : https://stackoverflow.com/questions/44377343/css-only-masonry-layout

반응형