【问题标题】:Responsive Square Divs Cross Browser Compatible响应式 Square Divs 跨浏览器兼容
【发布时间】:2017-11-21 00:39:26
【问题描述】:

我有一个 50/50 宽的页面。左半边有一排有六个 div。 标准:

  • 6 个方格必须始终保持方格。
  • 前 5 个方格应具有向右的边距/填充以用于分隔。
  • 所有六个方格必须保持在同一行。如果我能做到这一点,我可以在较小的视口中对响应能力进行必要的调整。
  • 跨浏览器兼容最新版本的 ie、chrome 和 firefox。

我的密码笔:https://codepen.io/johnsontroye/pen/zzNVBr

图片:

<body>
  <div class="container">
    <div class="column" style="margin-right: 20px">
      <div class="flex-container">
        <div class="flex-item">
          <div class="flex-item-inner">
            <div class="flex-item-inner-content">
              L1
            </div>
          </div>
        </div>
        <div class="flex-item">
          <div class="flex-item-inner">
            <div class="flex-item-inner-content">
              L2
            </div>
          </div>
        </div>
        <div class="flex-item">
          <div class="flex-item-inner">
            <div class="flex-item-inner-content">
              L3
            </div>
          </div>
        </div>
        <div class="flex-item">
          <div class="flex-item-inner">
            <div class="flex-item-inner-content">
              L4
            </div>
          </div>
        </div>
        <div class="flex-item">
          <div class="flex-item-inner">
            <div class="flex-item-inner-content">
              L5
            </div>
          </div>
        </div>
        <div class="flex-item">
          <div class="flex-item-inner">
            <div class="flex-item-inner-content">
              L6
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="column" style="margin-left: 20px; border: 1px black solid; height: 500px">

        Other stuff 

  <div>
</body>


.container {
  display: flex;
  flex-direction: row;
  padding: 25px;
  border: 2px red solid;
}

.column {
  width: 100%;
  height: 100%;
  float: left;
}

.flex-container {
  padding: 0;
  font-size: 0;
  border: 1px solid black;
  box-sizing: border-box;
}

.flex-item {
  position: relative;
  display: inline-block;
  height: 0;
  width: 100%;
  padding-top: 100%;
  border: 1px black solid;
  font-size: 20px;
  color: black;
  font-weight: bold;
  text-align: center;
  box-sizing: border-box;
}
@media (min-width: 480px) {
  .flex-item {
    width: 33.3333%;
    padding-top: 33.3333%;
  }
}
@media (min-width: 768px) {
  .flex-item {
    width: 16.6666%;
    padding-top: 16.6666%;
  }
}
.flex-item-inner {
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  margin-right: 25px;
  background: white;
  border: 1px solid red;
  box-sizing: border-box;
}
.flex-item-inner-content {
  border: 1px solid orange;
}

.flex-item:last-child .flex-item-inner {
  margin-right: 0;
  color: green;
}

【问题讨论】:

  • 那么你的问题是什么?

标签: html css flexbox


【解决方案1】:

这里的主要技巧是使div 成为正方形。

通常设置一个width,将height 设置为0 和一个等于widthpadding

.square {
  height: 0;
  width: 33%;
  padding-bottom: 33%;
  background: lightgray;
}
<div class="square">
  <div>
    Content
  </div>
</div>

现在,当我们添加display: flex 时,我们不能将padding 与百分比一起使用(Firefox 错误),并且我们不能将高度与百分比一起使用,因为我们使用了height: 0

为了克服这些问题,何时可以使用视口单位 vw,我们也可以使用 height 而不是 padding 来保持平方。

因此,我们没有设置像 calc((100% / 6) - 10px); 这样的宽度来平均分布 6 个项目,间距约为 10 像素宽,而是使用像这样的视口单位 calc(( (50vw - 65px) / 6) - 10px);

50vw 是浏览器宽度的一半,65pxcontainer 的左/右填充、50px 加上columns 之间的15px 间距之和。

这也允许我们跳过额外的flex-item-inner 元素,跳过在content 元素上使用position: absolute,并且由于我们没有在flex-item 上使用百分比作为高度,我们可以这样做这使内容居中

.flex-item-content {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

最终的结果是这样的

Fiddle demo

堆栈sn-p

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  padding: 25px;
  border: 2px red solid;
}
.column {
  flex-basis: calc(50% - 15px);
}
.flex-container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}
.flex-item {
  position: relative;
  flex-basis: calc(( (50vw - 65px) / 6) - 10px);
  height: calc(( (50vw - 65px) / 6) - 10px);
  background: white;
  border: 1px solid red;
  overflow: hidden;
}
.flex-item-content {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.flex-item:last-child .flex-item-content {
  color: green;
}

.column .other {
  padding: 15px;
  border: 1px solid black;
  padding-bottom: 35px; 
}
.column.left .other {
  margin-top: 10px;
}
.column.right .other:nth-child(n+2) {
  margin-top: 10px;
}

@media (max-width: 768px) {
  .flex-item {
    flex-basis: calc(( (50vw - 65px) / 3) - 10px);
    height: calc(( (50vw - 65px) / 3) - 10px);
  }  
  .flex-item:nth-child(n+4)  {
    margin-top: 12px;
  }  
}
@media (max-width: 480px) {
  .flex-item {
    flex-basis: calc(( (50vw - 65px) / 2) - 10px);
    height: calc(( (50vw - 65px) / 2) - 10px);
  }  
  .flex-item:nth-child(n+3)  {
    margin-top: 15px;
  }  
}
<div class="container">
  <div class="column left">
    <div class="flex-container">
      <div class="flex-item">
          <div class="flex-item-content">
            L1
          </div>
      </div>
      <div class="flex-item">
          <div class="flex-item-content">
            L2
          </div>
      </div>
      <div class="flex-item">
          <div class="flex-item-content">
            L3
          </div>
      </div>
      <div class="flex-item">
          <div class="flex-item-content">
            L4
          </div>
      </div>
      <div class="flex-item">
          <div class="flex-item-content">
            L5<br>L5
          </div>
      </div>
      <div class="flex-item">
          <div class="flex-item-content">
            L6
          </div>
      </div>
    </div>
    
    <div class="other">
      Other stuff - left
    </div>
    
  </div>
  <div class="column right">
    <div class="other">
      Other stuff - right
    </div>
 
    <div class="other">
      Other stuff - right
    </div>
  </div>
</div>

【讨论】:

  • 这是一个相当复杂的解决方案,但非常有效。感谢您花时间不仅解决问题,而且如此详细地解释解决方案。如果您不能很好地解释它以便我能理解您在做什么,我就不会使用它。如果我能给你的解释加分,我会的。
【解决方案2】:

这可以通过一些相当简单的代码来实现,只要父列的宽度保持在 50% 左右,并且正方形之间的空间不必严格等于某个值。 vw(视口宽度百分比)单位允许将一致的大小应用于元素的宽度和高度。

这是一个示例,我将其归结为最少的元素,一些注释有助于将其移入您的代码库。

  • .flex-itemheightflex-basisflex 的第三个值)进行实验以获得您喜欢的尺寸。
  • 不需要paddingmargin 值,因为justify-content: space-between; 有助于为我们计算。
  • 使用等于.flex-itemheightline-height 将允许具有display: inline-block;vertical-align: middle; 的内部元素居中。

.column {
  width: 48vw;
  height: 48vw;
  padding: 1vw;
  border: 1px solid #ccc;
}
.flex-container {
  display: flex;
  flex-flow: row;
  justify-content: space-between;
}
.flex-item {
  height: 6vw;
  line-height: 6vw;
  text-align: center;
  border: 1px solid #ccc;
  flex: 0 0 6vw;
}
<div class="column">
  <div class="flex-container">
    <div class="flex-item">
      L1
    </div>
    <div class="flex-item">
      L2
    </div>
    <div class="flex-item">
      L3
    </div>
    <div class="flex-item">
      L4
    </div>
    <div class="flex-item">
      L5
    </div>
    <div class="flex-item">
      L6
    </div>
  </div>
</div>

【讨论】:

  • 感谢您抽出宝贵时间回答这个问题。不幸的是,这不起作用,因为正方形之间的空间必须始终均匀分布。我最初确实尝试过您指出的 flexbox 解决方案。但是,正方形的解决方案需要具有绝对定位的内部 div。 Flexbox 不能很好地解决这个问题。不过再次感谢。
  • 如果有position: relative;,绝对定位的子元素应该可以在弹性元素中正常工作,除非我误解了什么。
  • 是的,它在 Chrome 中完美运行。但是,当我在 FireFox 中打开它时,布局混乱了。 “身高:0”似乎把它扔掉了。如果我删除它,它将在 FireFox 中运行,但在 Chrome 中则不行。我花了一整天的时间试图让它与 FlexBox 一起工作,最后不得不放弃,因为我无法让它工作。不是说它不起作用,只是说我无法让它起作用。
【解决方案3】:

仅在最新的浏览器中? CSS Grid 救援!它在最新版本中得到了很好的支持。您可能仍然需要一些供应商前缀;检查 CanIUse 了解详细信息。

这是一个叉子:https://codepen.io/jackmakesthings/pen/MoJNNV

.container {
  display: flex;
  flex-direction: row;
  padding: 25px;
  border: 2px red solid;
}

.column {
  width: 100%;
  height: 100%;
  float: left;
}

.grid-row {
  display: grid;
  grid-gap: 10px; /* set this to whatever space you need between boxes */
  grid-template-columns: repeat(6, 1fr); /* grid autosizes 6 columns */
}

.row-item {
  grid-column: 1 / 7; /* to span the whole row */
  border: 1px solid;
  padding: 10px;
}

.grid-item {
  position: relative;
  border: 1px solid;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

/* This is a nifty trick for getting those fixed aspect ratio boxes. */
.grid-item:before {
  content: '';
  float: left;
  width: 0;
  height: 0;
  padding-bottom: 100%;
}
.grid-item:after {
  display: table;
  clear: both;
}

/* Responsive grid changes? Sure! */

@media (max-width: 1000px) {

  /* We just have to change the grid template: */
  .grid-row {
    grid-template-columns: repeat(3, 1fr);
  }
  
  /* Unexpected thing I ran into - you also have to change this, or the grid stays big enough to accommodate the old 6-column-sized row-item. Makes sense, but vexed me for a minute!  */
  .row-item {
    grid-column: 1 / 4;
  }
}
<div class="container">
    <div class="column" style="margin-right: 20px">
      <div class="grid-row">
        <div class="grid-item">L1</div>
        <div class="grid-item">L2</div>
        <div class="grid-item">L3</div>
        <div class="grid-item">L4</div>
        <div class="grid-item">L5</div>
        <div class="grid-item">L6</div>
        <div class="row-item">some other thing</div>
        <div class="row-item">and another</div>
      </div>
    </div>

    <div class="column" style="margin-left: 20px; border: 1px black solid; height: 500px">
      
        Other stuff 
     
  <div>

【讨论】:

  • 这是完美的。正是我想要的。我知道我说过我可以处理响应性,但我以前从未使用过 CSS 网格。您是否介意在 1000 像素处添加一个媒体查询以切换到两行,每行 3 个正方形。就这样我可以看到技术。谢谢!
  • 当然!更新了 sn-p 和笔。
  • 宾果游戏......完美的 Chrome!在 Firefox 中按原样分崩离析。但是,我假设它可以在 FireFox 中使用前缀?
  • 它应该 - 就像我说的那样,您需要查看caniuse.com 以获取有关如何使用它的详细信息和资源。可能存在我不知道的规范的 Firefox 错误,但如果是这样,它们可能已记录在那里。
  • 其实FF不喜欢的不是CSS Grid,而是正方形的CSS。它是FF中的一个矩形。有什么建议让它在 FF 中保持正方形?
猜你喜欢
  • 2012-08-09
  • 2015-03-07
  • 2016-09-30
  • 2011-06-07
  • 1970-01-01
  • 2011-07-03
  • 2011-06-18
  • 1970-01-01
相关资源
最近更新 更多