css - 无媒体查询如何实现3列桌面转1列移动布局
问题描述
在这里查看了几个问题,但它们并不能完全解决我正在寻找的问题。
假设我有一个网站并且我想要。在桌面上我想要这个:
这很简单。grid-template-columns: repeat(3, 33%)
(基本上)
但是,在移动设备上,我想要这个
我遇到的是在它翻转到单列之前发生的事情:
我正在尝试clamp()
,minmax()
和各种各样的东西,但没有任何东西能按我的意愿工作。是的,我完全可以使用媒体查询,但我希望使用现代 CSS(如钳位、网格、最小最大值等)创建真正流畅的网格/弹性布局,这样就不需要媒体查询来更改基本布局。
我知道这不起作用,但作为起点,这里是我的 100 次尝试之一的简单版本:) 在这个版本中,我试图使用钳位从重复 (3) 切换到重复 (1)。
.wrapper {
display: grid;
gap: 15px;
grid-template-columns: repeat(clamp(1, calc(100% - 500px), 3), 33%);
}
.one {
background: red;
}
.two {
background: green;
}
.three {
background: blue;
}
<div class="wrapper">
<div class="item one"><h3>Example A</h3></div>
<div class="item two"><h3>Example Two</h3></div>
<div class="item three"><h3>Third Example</h3></div>
</div>
解决方案
这是一个使用max(0px, (400px - 100vw)*1000)
内部 flex-basis 的想法。0px
如果100vw
(屏幕尺寸)大于400px
或非常大的值,则此公式将给出相反的情况,给每个元素一个大flex-basis
并创建一个包装。只需调整400px
其中发挥的作用@media (max-width:400px)
.container {
display:flex;
flex-wrap:wrap;
}
.container div {
height:100px;
border:2px solid;
background:red;
flex-basis:max(0px, (400px - 100vw)*1000);
flex-grow:1;
}
<div class="container">
<div></div>
<div></div>
<div></div>
</div>
使用 CSS 网格可以如下所示:
.container {
display:grid;
grid-template-columns:repeat(auto-fill,minmax(clamp(30%, (400px - 100vw)*1000, 100%),1fr));
grid-gap:5px;
}
.container div {
height:100px;
border:2px solid;
background:red;
}
<div class="container">
<div></div>
<div></div>
<div></div>
</div>
一个类似的问题,我正在控制没有媒体查询的最大列数:CSS grid maximum number of columns without media queries
我们可以扩展上述解决方案以考虑更复杂的情况。
从 6 列移动到 3 列再到 1 列的示例:
.container {
display:grid;
grid-template-columns:
repeat(auto-fill,
minmax(clamp(clamp(15%,(800px - 100vw)*1000, 30%), (400px - 100vw)*1000, 100%)
/* if(screen> 800px) 15% elseif(screen> 400px) 30% else 100% */
,1fr));
grid-gap:5px;
}
.container div {
height:100px;
border:2px solid;
background:red;
}
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
要了解这些值,请考虑以下范围:
100%/7 100%/6 100%/5 100%/4 100%/3 100%/2 100%/1
14.3% 16.7% 20% 25% 33.3% 50% 100%
要获得 6 列,我们需要范围内的值]14.3% 16.7%]
(我考虑过15%
) 要获得 3 列,我们需要范围内的值]25% 33.3%]
(我考虑过30%
)
我们只是避免边缘以确保我们考虑到差距。
一个使用 CSS 变量的更通用的解决方案,我将在其中添加0.1%
以确保该值足够大以获得所需的列数并且它可以保持差距。
让我们也添加一些动态着色(相关:如何根据高度或宽度改变 <div> 元素的颜色?)
.container {
/* first breakpoint*/
--w1:800px;
--n1:6;
/* second breakpoint*/
--w2:400px;
--n2:3;
display:grid;
grid-template-columns:
repeat(auto-fill,
minmax(clamp(clamp(100%/(var(--n1) + 1) + 0.1%, (var(--w1) - 100vw)*1000,
100%/(var(--n2) + 1) + 0.1%), (var(--w2) - 100vw)*1000,
100%), 1fr));
grid-gap:5px;
margin:10px 0;
}
.container div {
height:100px;
border:2px solid;
background:
linear-gradient(blue 0 0) 0 /1% calc(var(--w2) - 100vw),
linear-gradient(green 0 0) 0 /1% calc(var(--w1) - 100vw),
red;
}
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="container" style="--w1:900px;--n1:8;--w2:500px;--n2:4;grid-gap:10px;">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="container" style="--w1:600px;--n1:4;--n2:2;grid-gap:2vw;">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
使用 flexbox,我们可以有不同的(可能是想要的)行为,其中一行的最后一项将占用所有可用空间:
.container {
/* first breakpoint*/
--w1:800px;
--n1:6;
/* second breakpoint*/
--w2:400px;
--n2:3;
display:flex;
flex-wrap:wrap;
margin:10px 0;
}
.container div {
height:100px;
border:2px solid;
margin:5px;
flex-basis:clamp(clamp(100%/(var(--n1) + 1) + 0.1% ,(var(--w1) - 100vw)*1000,
100%/(var(--n2) + 1) + 0.1%),(var(--w2) - 100vw)*1000,
100%);
flex-grow:1;
box-sizing:border-box;
background:
linear-gradient(blue 0 0) 0 /1% calc(var(--w2) - 100vw),
linear-gradient(green 0 0) 0 /1% calc(var(--w1) - 100vw),
red;
}
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="container" style="--w1:900px;--n1:8;--w2:500px;--n2:4;">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="container" style="--w1:600px;--n1:4;--n2:2;">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
推荐阅读
- python - 参数 1 必须是类型,而不是 super() 调用上的 pygame.surface
- ruby - 一次初始化多个对象?
- jquery - 根据选择使用 Fieldset 禁用和隐藏表单元素
- flutter - 为什么我的一种状态在我的测试期间没有被触发
- c++ - SortedVector 没有正确调用函数?
- flask - 如何在事件处理程序之外发出 socketio 消息
- c - 即使向量不同,也多次使用相同的函数
- swift - 如何在符合协议的非 RawRepresentable 枚举上实现 CustomStringConvertible?
- node.js - mongoose 加载 json 会删除 Schema Types ObjectId 数据吗?
- amazon-s3 - 无法从 Amazon S3 加载 Snowflake 外部表