css 容器布局问题?

HTML 代码 (假设父容器可以嵌套无数个同级的item, 父容器高度自适应就行)

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
    </head>

    <body>
        <div class="rxc-wrapper bg-primary text-white p-3">
            <div class="rxc-container bg-success p-3">
                <div class="item"></div>
                <div class="item"></div>
                <div class="item"></div>
                <div class="item"></div>
                <div class="item"></div>
                <div class="item"></div>
                <div class="item"></div>
                <div class="item"></div>
                <div class="item"></div>
                <div class="item"></div>
                <div class="item"></div>
                <div class="item"></div>
            </div>
        </div>
    </body>
</html>

CSS 代码

.item {
    width: 25%;
    height: 100px;
    border: 1px solid;
}

.rxc-container {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

需求描述

除了flex以外可以使用其他布局方式, 能实现效果就行

  • 根据定义item宽度百分比 25% 和间距 1rem, 需要实现每行均分

    • 如果宽度是 25% 每行显示4个item
    • 如果宽度是 50% 每行显示5个item
    • 以此类推, 但是间距永远保持1rem

遇到的问题

如果算上间距 + 宽度, 会溢出, 也就是说, 在 4 个 item 25% 宽加上 1rem 间距, 一行不可能显示4个, 所以需要把间距减掉在算宽度

以下是目前的效果

image.png

期望的得道的效果

image.png

图中有点问题, 最下面间距应该为1rem, 但我代码里没有实现
代码如下, 我这边在内部嵌套了一个div, 再用 :nth-child 才能实现类似的需求
然后项问一下有没有什么其他更好的实现方法?

HTML

<div class="rxc-wrapper bg-primary text-white p-3">
  <div class="rxc-container bg-success p-3">
    <div class="item">
        <div class="box"></div>
    </div>
    <div class="item">
        <div class="box"></div>
    </div>
    <div class="item">
        <div class="box"></div>
    </div>
    <div class="item">
        <div class="box"></div>
    </div>
    <div class="item">
        <div class="box"></div>
    </div>
    <div class="item">
        <div class="box"></div>
    </div>
    <div class="item">
        <div class="box"></div>
    </div>
    <div class="item">
        <div class="box"></div>
    </div>
    <div class="item">
        <div class="box"></div>
    </div>
    <div class="item">
        <div class="box"></div>
    </div>
    <div class="item">
        <div class="box"></div>
    </div>
    <div class="item">
        <div class="box"></div>
    </div>
  </div>
</div>

CSS

.box {
    width: 100%;
    height: 100px;
    border: 1px solid;
}

.item {
    width: 25%;
    margin-bottom: 1rem;
}

.rxc-container {
    display: flex;
    flex-wrap: wrap;
}

.item:nth-child(4n) {
    padding-left: .5rem !important;
}

.item:nth-child(4n-1),
.item:nth-child(4n-2) {
    padding-left: .5rem !important;
    padding-right: .5rem !important;
}

.item:nth-child(4n-3) {
    padding-right: .5rem !important;
}
阅读 1.8k
2 个回答

用 calc 去计算就好了,你要有间隙,那 item 肯定就不能是绝对的宽度,宽度应该由:

<单个 item 宽度> = (<外部盒子宽度> - <间隙>) / <单行数量>

如下面这个例子,假设这些位置的大小都是 1rem 那 item 的宽度就可以设置成 width: calc((100% - 1rem * 5) / 4),并且再给上 margin-left: 1rem

.item {
  width: calc((100% - 1rem * 5) / 4);
  margin-left: 1rem;
}

image.png

当然,一般情况下,外部盒子内部的边距,我们可以用 padding 来填充一下。

image.png

简单调整一下 CSS

.box {
  width: 100%;
  height: 100px;
  border: 1px solid;
}

.rxc-container {
  display: flex;
  flex-wrap: wrap;
  padding: 1rem;
}

.item {
  width: calc((100% - 1rem * 3) / 4);
  margin-right: 1rem;
  margin-bottom: 1rem;
}

.item:nth-child(4n) {
  margin-right: 0;
}

/*最后一排的 4 个,不要显示*/
.item:nth-last-child(-n+4) {
  margin-bottom: 0;
}

当然,如果使用 grid 的话,会更简单


.item {
  height: 100px;
  border: 1px solid;
}

.rxc-container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  padding: 1rem;
}

一个很简单的问题,你考虑过calc吗?https://www.runoob.com/cssref/func-calc.html

calc() 函数用于动态计算长度值。
需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);
任何长度值都可以使用calc()函数进行计算;
calc()函数支持 "+", "-", "*", "/" 运算;
calc()函数使用标准的数学运算优先级规则;
支持版本:CSS3

你把宽度用计算属性处理下就行,rem本身是相对固定的值,百分比是动态值,你直接宽度赋值时计算下就行;

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题