在没有媒体查询的情况下如何实现3列桌面到1列移动版式 [英] Without media queries how to achieve 3 column desktop to 1 column mobile layout

查看:42
本文介绍了在没有媒体查询的情况下如何实现3列桌面到1列移动版式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这里有几个问题,但是他们并不能完全解决我要找的问题.

说我有一个网站,我想要.在台式机上,我想要这样:

这很容易. grid-template-columns:重复(3,33%)(基本上)

但是,我想要在移动设备上

我正在遇到的事情是在它翻转到单列之前发生的:

我正在尝试 clamp() minmax(),以及其他各种方法,但是没有一种能满足我的需要.是的,我可以完全使用媒体查询,但是我希望使用现代CSS(如钳位,网格,minmax等)创建真正的流畅的网格/柔版布局,因此不需要对基本布局进行更改的媒体查询./p>

我知道这是行不通的,但是作为请求的起点,这是我100次尝试之一的简单版本:)在此版本中,我试图使用钳位器从repeat(3)切换到repeat(1)).

  .wrapper {显示:网格;间隙:15px;网格模板列:repeat(clamp(1,calc(100%-500px),3),33%);}.一 {背景:红色;}.二 {背景:绿色;}.三 {背景:蓝色;}  

 < div class ="wrapper">< div class ="item one">< h3>例子A</h3></div>< div class ="item two">< h3>示例2</h3></div>< div class ="item three">< h3>第三示例</h3></div></div>  

解决方案

这里是在flex-basis内部使用 max(0px,(400px-100vw)* 1000)的想法.如果 100vw (屏幕尺寸)大于 400px (或者在相反情况下为一个很大的值),则此公式将给出 0px flex-basis 并创建包装.只需调整起 @media(最大宽度:400px)

作用的 400px

  .container {显示:flex;flex-wrap:wrap;}.container div {高度:100px;边框:2px实线;背景:红色;flex-basis:max(0px,(400px-100vw)* 1000);flex-grow:1;}  

 < div class ="container">< div></div>< div></div>< div></div></div>  

使用CSS网格,如下所示:

  .container {显示:网格;grid-template-columns:repeat(auto-fill,minmax(clamp(30%,(400px-100vw)* 1000,100%),1fr));grid-gap:5px;}.container div {高度:100px;边框:2px实线;背景:红色;}  

 < div class ="container">< div></div>< div></div>< div></div></div>  

一个类似的问题,我可以控制没有媒体查询的最大列数: CSS网格,没有媒体查询的最大列数


我们可以扩展上述解决方案以考虑更复杂的情况.

从6列移至3列至1列的示例:

  .container {显示:网格;网格模板列:重复(自动填充,minmax(clamp(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 {高度:100px;边框:2px实线;背景:红色;}  

 < 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%/114.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 {/*第一个断点*/--w1:800px;--n1:6;/*第二个断点*/--w2:400px;--n2:3;显示:网格;网格模板列:重复(自动填充,minmax(钳位(钳位(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;边距:10px 0;}.container div {高度:100px;边框:2px实线;背景:线性渐变(蓝色0 0)0/1%calc(var(-w2)-100vw),线性渐变(绿色0 0)0/1%calc(var(-w1)-100vw),红色的;}  

 < 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 {/*第一个断点*/--w1:800px;--n1:6;/*第二个断点*/--w2:400px;--n2:3;显示:flex;flex-wrap:wrap;边距:10px 0;}.container div {高度:100px;边框:2px实线;边距:5px;flex-basis:clamp(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;背景:线性渐变(蓝色0 0)0/1%calc(var(-w2)-100vw),线性渐变(绿色0 0)0/1%calc(var(-w1)-100vw),红色的;}  

 < 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>  

Looked into a few questions here but they don't quite solve what I'm looking for.

Say I have a website and I want. On desktop I want this:

This is easy. grid-template-columns: repeat(3, 33%) (basically)

On mobile, however, I want this

What I'm running into is happens before it flips to a single column:

I'm trying clamp(), minmax(), and all sorts of things but nothing ever works as I want. Yes, I can totally use a media query but I was hoping to create a truly fluid grid/flex layout using modern CSS like clamp, grid, minmax, etc so there wouldn't be a need for media queries for basic layout changes.

I know this doesn't work but as a starting point as requested here's a simple version of one of my 100 attempts :) In this version I was trying to use clamp to switch from a repeat(3) to repeat(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>

解决方案

Here is an idea using max(0px, (400px - 100vw)*1000) inside flex-basis. This formula will eiter give 0px if 100vw (screen size) is bigger than 400px or a very big value in the opposite case giving each element a big flex-basis and create a wrapping. Simply adjust the 400px which play the role of @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>

Using CSS grid it can be like below:

.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>

A similar question where I am controling the maximum number of columns without media query: CSS grid maximum number of columns without media queries


We can scale the above solution to consider more complex cases.

Example of moving from 6 to 3 to 1 column:

.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>

To understand the values consider the following ranges:

100%/7  100%/6  100%/5  100%/4  100%/3  100%/2  100%/1
 14.3%  16.7%    20%     25%     33.3%   50%     100%

To get 6 columns we need a value in the range ]14.3% 16.7%] (I considered 15%) To get 3 columns we need a value in the range ]25% 33.3%] (I considered 30%)

We simply avoid the edges to make sure we account for the gaps.

A more generic solution using CSS variables where I will add 0.1% to make sure the value is big enough to get the needed number of column and it can hold the gap.

Let's also add some dynamic coloration (related: How to change the color of <div> Element depending on its height or width?)

.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>

Using flexbox where we can have a different (probably wanted) behavior where the last item of a row will take all the free space:

.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>

这篇关于在没有媒体查询的情况下如何实现3列桌面到1列移动版式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆