css3 的不同订单项和布局具有相同的 html

Different order items and layout with css3 by resolution with the same html

我无法在保持相同 HTML 布局的情况下获得响应结果。

我需要:

  1. 如果屏幕宽度在 1024px 之前或之后,则有两种不同的块顺序,
  2. => 1024px,我必须按两列显示项目,并确保块 1、2、3 在左列内,块 4、5 在右列内(包装的高度必须适合内容 ),
  3. < 1024px,所有块都在唯一列内,但顺序不同。

像这样...

1024 像素及更多

1023px 及以下

当前CSS

@media screen and (max-width: 1023px) {
    .production-container{
        display: grid;
        grid-template-columns: repeat(1, 1fr);
        padding: 0 var(--standard-margin) 0 var(--standard-margin);
        justify-content: stretch;
        min-height: 200px;
    }

    aside.production-block{
        max-width: 100vw;
        width: 100%;
        display: flex;
        flex: 1;
        flex-direction: column;
        margin: 24px 0;
        display: grid;
        grid-template-rows: 1fr auto;
        break-inside: avoid;
    }

    .production-container > .production-block-4 {
        order: 1;
    }

    .production-container > .production-block-1 {
        order: 2;
    }

    .production-container > .production-block-2 {
        order: 3;
    }

    .production-container > .production-block-5 {
        order: 4;
    }

    .production-container > .production-block-3 {
        order: 5;
    }

}

@media screen and (min-width: 1024px) {

   .production-container{
        column-count: 2;
        column-gap: 50px;
        max-width: 1024px;
        background: linear-gradient( var(--text-light-color), var(--text-light-color) ) no-repeat center/1px 100%; /* vertical line in the center */
   }
   .production-block {
        margin: 0 0 10px 0;
        break-inside: avoid;
        max-width: 520px;
    }

}

最重要的问题是,在最大分辨率下,我无法强制每个块位于第一列或第二列,它们会根据高度内容自然地放置自己。也许,我应该更改与最小分辨率兼容的 css 策略,但是当我使用“网格”时,每一行的高度都会产生很大的空白。

有人有想法吗?

实际上它有效,你几乎完成了。 只需将订单添加到:

@media screen and (min-width: 1024px) {

   .production-container{
        column-count: 2;
        column-gap: 50px;
        max-width: 1024px;
        background: linear-gradient( var(--text-light-color), var(--text-light-color) ) no-repeat center/1px 100%; /* vertical line in the center */
   }
   
   .production-block {
        margin: 0 0 10px 0;
        break-inside: avoid;
        max-width: 520px;
        border: 1px solid red;
    }
    
    .production-container > .production-block-4 {
        order: 1;
    }

    .production-container > .production-block-1 {
        order: 2;
    }

    .production-container > .production-block-2 {
        order: 3;
    }

    .production-container > .production-block-5 {
        order: 4;
    }

    .production-container > .production-block-3 {
        order: 5;
    }
}

我找到了 grid-template-areas 的解决方案。

@media screen and (min-width: 1024px) {

   .production-container{
        height: 100%;
        display: grid;
        grid-template-areas: "zone-row1-column1 zone-row1-column2" "zone-row2-column1 zone-row2-column2" "zone-row3-column1 zone-row3-column2";
        grid-template-rows: minmax(290px, auto) 1fr;
        grid-template-columns: 1fr 1fr;
        grid-gap: 50px;
        max-width: 1024px;
        background: linear-gradient( var(--text-light-color), var(--text-light-color) ) no-repeat center/1px 100%; /* vertical line in the center */
   }
    
    .production-container > .production-block-4 {
        grid-area: zone-row1-column2;
    }

    .production-container > .production-block-1 {
         grid-area: zone-row1-column1;
    }

    .production-container > .production-block-2 {
        grid-area: zone-row2-column1;
    }

    .production-container > .production-block-5 {
        grid-area: zone-row2-column2;
    }

    .production-container > .production-block-3 {
        grid-area: zone-row3-column1;
    }
}

You must add "zone-row3-column2" even if it does not use inside grid-template-areas because there are 2 columns anyway.

@media screen and (min-width: 1024px) {
    .production-container{      
       padding: 0 var(--standard-margin) 0 var(--standard-margin);      
       min-height: 200px;
    }
    
    .production-block {
        border: 1px solid blue;
        width:50%;
    }
    .production-block-1{
        float: left;
        clear:left
    }
    .production-block-2{
        float: left;
        clear:left
    }
    .production-block-3{
        float: left;
        clear:left
    }
    .production-block-4{
        margin-left:50%
    }
    .production-block-5{
        margin-left:50%
    }
}

I don´t manage to force each block to be on the first or second column, they place thereself naturally based on height content.

在这种情况下,您可以使用 grid-row-startgrid-row-end

来管理 网格

when I used "grid", each row got a height that made big blank spaces.

对于此解决方案,您尝试将 高度 设置为 height: min-content。如果该块没有任何内容,它就会崩溃。但是,应该记住 padding,它们在没有内容的情况下提供额外的高度。

*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

:root {
  --bg1: hsl(34, 96%, 54%);
  --bg2: hsl(189, 99%, 60%);
  --bg3: hsl(345, 100%, 60%);
  --bg4: hsl(128, 65%, 48%);
  --bg5: hsl(210, 99%, 60%);
  --standard-margin: 1rem;
}

.production-block-1,
.production-block-2,
.production-block-3,
.production-block-4,
.production-block-5 {
  height: min-content;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  padding: 1rem;
}

.production-block-1 {
  grid-row-start: 2;
  background-color: var(--bg1);
}

.production-block-2 {
  grid-row-start: 3;
  background-color: var(--bg2);
}

.production-block-3 {
  grid-row-start: 5;
  background-color: var(--bg3);
}

.production-block-4 {
  grid-row-start: 1;
  background-color: var(--bg4);
}

.production-block-5 {
  grid-row-start: 4;
  background-color: var(--bg5);
}

.production-container {
  display: grid;
  gap: 1rem;
}

@media screen and (max-width: 1023px) {
  .production-container {
    grid-template-columns: repeat(1, 1fr);
    padding: 0 var(--standard-margin) 0 var(--standard-margin);
  }
}

@media screen and (min-width: 1024px) {
  .production-container {
    grid-template-columns: repeat(2, 1fr);
  }
  .production-block-1 {
    grid-row-start: 1;
  }
  .production-block-2 {
    grid-row-start: 2;
  }
  .production-block-3 {
    grid-row-start: 3;
  }
  .production-block-4 {
    grid-row-start: 1;
  }
  .production-block-5 {
    grid-row-start: 2;
  }
}
<div class="production-container">
  <div class="production-block-1">1</div>
  <div class="production-block-2">2</div>
  <div class="production-block-3">3</div>
  <div class="production-block-4">4</div>
  <div class="production-block-5">5</div>
</div>

您可以从网格布局切换到柱状 CSS 布局(直到砌体 CSS 网格布局广泛可用 https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Masonry_Layout , here is an example https://codepen.io/gc-nomade/pen/ExXNXdd 如果激活,此时对于 FF)

下面代码段中的 HTML 代码演示 没有空白 space

它是如何工作的?

  • 1 - < 1024px grid 单列使用顺序 (如果没有模板,网格创建单列已设置)

  • 2 - > 1023px column-countdisplay:block 用于 2 列布局。 break-after:always & break-before: column 将适用于使用 chrome 引擎的浏览器(参见 CSS Fragmentation )。

  • 3 - 对于 firefox & >1023px 在第三个元素上加一个 hudge margin-bottom,所以只能有 3在第一列。这个边距不会应用到容器内部,npr 会溢出它,它只会将第四个推到下一列。 Firefox 可以通过过滤(直到它理解 break-after:always 和列 CSS)以应用仅供 Firefox 浏览器使用的边距技巧:

@-moz-document url-prefix() {
  .grid > div:nth-child(3) {
   margin-bottom:100%;
   }
}

Live Example 主容器只需要 包裹 2 列所需的高度,无论子项的高度如何,您会注意到在第二个示例中, col 2 更高,Chrome(s) 似乎遵循打破规则,第一列不需要是最高的。

.grid {
  display: grid;
  gap: 1em;
  border:solid;
  background:gray;
    
}

.grid > div:nth-child(1) {
  order: 1;
}
.grid > div:nth-child(2) {
  order: 2;
}
.grid > div:nth-child(3) {
  order: 4;
}
.grid > div:nth-child(4) {
  order: 0;
}
.grid > div:nth-child(5) {
  order: 3;

}

@media (min-width: 1024px) {
  .grid {
    display: block;
    column-count: 2;
  }
  .grid > div {
    margin-bottom: 1em;
  }
  .grid > div:nth-child(3) {
    break-after:always;
  }
  .grid> div:nth-child(4) {
      break-before: column;
      }
  @-moz-document url-prefix() {
    .grid > div:nth-child(3) {
    margin-bottom:100%;/* trick for FF that won't show that margin if the last inside a column but not in the last column */
  }
}
}

/* demo */
.grid {
  counter-reset: divs;
}
.grid > div {
  display: grid;
}
.grid > div::before {
  counter-increment: divs;
  content: counter(divs);
  color: white;
  margin: auto;
  font-size: clamp(10px, 5vmin, 30px);
}
.grid > div:nth-child(1) {
  background: #fa9917;
  height: 100px;
}
.grid > div:nth-child(2) {
  background: #33e0fe;
  height: 160px;
}
.grid > div:nth-child(3) {
  background: #ff3366;
  height: 80px;
}
.grid > div:nth-child(4) {
  background: #2bc940;
  height: 80px;
}
.grid > div:nth-child(5) {
  background: #3399fe;
  height: 160px;
}
<div class=grid>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
Hello the world
<hr>
Make second column taller to see where the fourth stands before you test or ask ;)
<div class=grid>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div style="height:600px"></div>
</div>

最后,我建议使用一点点 javascript 或众所周知的坚固砌体库来避免 FF CSS 技巧。技巧随时都可能过时 ;)

  • 不知道关于 CSS 碎片的 Safari 行为。

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fragmentation

CSS Fragmentation is a module of CSS that defines how content is displayed when it is broken (fragmented) across multiple pages, regions, or columns.

Fragmentation occurs when an inline box wraps onto multiple lines. It also occurs when a block spans more than one column inside a column layout container, or spans a page break when printed. Each piece of the rendering for the element is called a fragment.

关于原生 CSS 网格砌体,您可以查看和阅读:https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

我找到了一个更好的解决方案,使用网格来制作两列。

Notice : when you use grid, that forces the template to be aligned with columns and rows as well that can make blank space when blocks on the same row have not a similar height...

制作空格的模板

*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

:root {
  --bg1: hsl(34, 96%, 54%);
  --bg2: hsl(189, 99%, 60%);
  --bg3: hsl(345, 100%, 60%);
  --bg4: hsl(128, 65%, 48%);
  --bg5: hsl(210, 99%, 60%);
  --standard-margin: 1rem;
}

.production-block-1,
.production-block-2,
.production-block-3,
.production-block-4,
.production-block-5 {
  height: min-content;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  padding: 1rem;
}

.production-block-1 {
  grid-row-start: 2;
  background-color: var(--bg1);
}

.production-block-2 {
  grid-row-start: 3;
  background-color: var(--bg2);
}

.production-block-3 {
  grid-row-start: 5;
  background-color: var(--bg3);
}

.production-block-4 {
  grid-row-start: 1;
  background-color: var(--bg4);
}

.production-block-5 {
  grid-row-start: 4;
  background-color: var(--bg5);
}

.production-container {
  display: grid;
  gap: 1rem;
}

@media screen and (max-width: 1023px) {
  .production-container {
    grid-template-columns: repeat(1, 1fr);
    padding: 0 var(--standard-margin) 0 var(--standard-margin);
  }
}

@media screen and (min-width: 1024px) {
  .production-container {
    grid-template-columns: repeat(2, 1fr);
  }
  .production-block-1 {
    grid-row-start: 1;
    height: 150px;
  }
  .production-block-2 {
    grid-row-start: 2;
    height: 200px;
  }
  .production-block-3 {
    grid-row-start: 3;
  }
  .production-block-4 {
    grid-row-start: 1;
    height: 300px;
  }
  .production-block-5 {
    grid-row-start: 2;
    height: 250px;
  }
}
<h1>Grid template with blank spaces</h1>
<div class="production-container">
  <div class="production-block-1">1</div>
  <div class="production-block-2">2</div>
  <div class="production-block-3">3</div>
  <div class="production-block-4">4</div>
  <div class="production-block-5">5</div>
</div>

我的解决方案(砌体+断柱)

为了避免空格,您有一个基于 Masonry with flexbox and add a break column inside the HTML template 的解决方案。

Notice : That solution needs :

  1. add a html tag with break-column class
  2. use height: 100%; on wrappers html tags.
  3. The orders of the biggest resolution is the order in the html template, it is for the smallest resolution, you change the order.

*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

:root {
  --bg1: hsl(34, 96%, 54%);
  --bg2: hsl(189, 99%, 60%);
  --bg3: hsl(345, 100%, 60%);
  --bg4: hsl(128, 65%, 48%);
  --bg5: hsl(210, 99%, 60%);
  --standard-margin: 1rem;
}

body, html{
    height: 100%;
}

.production-block-1,
.production-block-2,
.production-block-3,
.production-block-4,
.production-block-5 {
  height: min-content;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  padding: 1rem;
}

.production-block-1 {
  grid-row-start: 2;
  background-color: var(--bg1);
}

.production-block-2 {
  grid-row-start: 3;
  background-color: var(--bg2);
}

.production-block-3 {
  grid-row-start: 5;
  background-color: var(--bg3);
}

.production-block-4 {
  grid-row-start: 1;
  background-color: var(--bg4);
}

.production-block-5 {
  grid-row-start: 4;
  background-color: var(--bg5);
}

.production-container {
  display: grid;
  gap: 1rem;
}

@media screen and (max-width: 1023px) {
  .production-container {
    grid-template-columns: repeat(1, 1fr);
    padding: 0 var(--standard-margin) 0 var(--standard-margin);
  }
}

@media screen and (min-width: 1024px) {
  .production-container {
      display: flex;
      flex-flow: column wrap;
      max-width: 1024px;
      height: 100%;
      background: linear-gradient( var(--text-light-color), var(--text-light-color) ) no-repeat center/1px 100%;
  }
  /* Force new columns */
 .production-container::before,
 .production-container::after {
    content: "";
    flex-basis: 100%;
    width: 0;
    order: 2;
  }
  .break-column {
    flex-basis: 100%;
    width: 0 !important;
  } 
  .production-container > .production-block{
    width: 500px;
  } 
  .production-block-1 {
    height: 150px;
  }
  .production-block-2 {
    height: 200px;
  }
  .production-block-4 {
    height: 300px;
  }
  .production-block-5 {
    height: 250px;
  }
}
<h1>Masonry solution without blank space</h1>
<div class="production-container">
  <div class="production-block production-block-1">1</div>
  <div class="production-block production-block-2">2</div>
  <div class="production-block production-block-3">3</div>
  <div class="break-column"></div>
  <div class="production-block production-block-4">4</div>
  <div class="production-block production-block-5">5</div>
</div>