纯CSS实现自适应正方形的几种方式

原文链接: 点我

在写页面布局时候正方形对我们来说应该很常见,比如商品列表展示,头像展示, 在微博上发布图片的展现等


正方形用固定的形式写很简单 直接长=宽写固定的值如下

1 <div class="square"></div>
2 .square{
3      width: 50%;
4      height: 50vw;
5      background: #ccc;
6 }

 

这样写没有问题,但是如果想在移动端实现宽度自适应呢,利用javascript会不会有点太麻烦啦,确实很麻烦啦,那么就让我们用纯CSS的方式来实现一下

方法一:
利用.CSS3 vw 单位,vw是相对于视口的宽度。视口被均分为100单位的vw。1vw = 1% viewport width

1 <div class="square">hello,viewport</div>
2 <style>
3 .square {
4   width: 50%;
5   height: 50vw;
6   background: #ccc;
7 }
8 </style>

方法二:
设置垂直方向的padding撑开容器(padding可以用百分比,百分比是根据它包含块的width来确定的,也就是父级元素的width)

1 <div class="square2"></div>
2 <style>
3 .square2{
4   width: 50%;
5   padding-bottom:100%;
6   height:0;
7 }
8 </style>

在这里需要注意一下,如果不写hegith的话,正方形内文字会溢出,溢出的高度正好就是文字所占空间的高度。


有的人肯定会想padding-bottom换成padding-top可以吗,那我们就来试试

1 <div class="square2"></div>
2 <style>
3 .square3{
4   width: 50%;
5   padding-top:100%;
6   height:0;
7 }
8 </style>

可以看出来在正方形中有内容的时候,内容会在正方形外面,这是因为默认文字是从左到右,从上到下的排列所以paddin-top以后文字会在正方形外面,如果就想用padding-top来写那么请看方法三

方法三:

利用双层嵌套来写,将外层的div的position设置relative,内层的position设置为absoult,利用绝对定位消除空间占用
分别看设置成padding-top/padding-bottom的效果

 1 <div class="square3">
 2 <div class="con">
 3 内容
 4 </div>
 5 </div>
 6 <div class="square3-2">
 7 <div class="con">
 8 内容
 9 </div>
10 </div>
11 <style>
12 .square3{
13   padding-bottom:100%;
14   height: 0;
15   background:#ccc;
16   width: 50%;
17   position: relative;
18 }
19 .square3-2{
20   padding-top:100%;
21   height: 0;
22   background:#ccc;
23   width: 50%;
24   position: relative;
25 }
26 .con{
27   position: absolute;
28   width: 100%;
29   height: 100%;
30 }
31 </style>

运行之后我们发现写padding-top还是不可以,我们来检查代码发现,在写内层的div时候没有给top,left的值,让我们把top,left加上再看看

1 <style>
2 .con{
3   position: absolute;
4   width: 100%;
5   height: 100%;
6   top:0;
7   left:0;
8 }
9 </style>

所以如果用padding-top的时候一定要记得添加top,left

还可以利用伪元素

 1 <div class="square4">
 2   伪元素
 3 </div>
 4 
 5 <div class="square4">
 6 <!-- 利用绝对定位 -->
 7 <div class="con">伪元素</div>
 8 </div>
 9 <style>
10 .square4 {
11   width: 100%;
12   background: #ccc;
13 }
14 .square4:after {
15   content: '';
16   display: block;
17   padding-top: 100%;
18 }
19 .con{
20   width: 100%;
21   height: 100%;
22   position: absolute;
23 }
24 </style>

其实我们平时再用到正方形的时候比较多的情况是图片,让图片正方形且自适应,下面也列出了几种方法

方法一:
通过style:background的方式写在标签内部

1 <div class="square1" style="background: url(images/square.jpg)no-repeat center /cover"></div>
2 <style>
3 .square1{
4   width: 50%;
5   padding-top:100%;/*padding-bottom:100%也可以*/
6   height: 0; /*可不写*/
7 }
8 </style>

这里写padding-top/bottom 都可以,height也可以不写高度运行效果如下:


方法二:
用img的是形式

 1 <div class="square2">
 2 <div class="con">
 3 <img src="images/square.jpg" class="squareimg"/>
 4 </div>
 5 </div>
 6 <style>
 7 .squareimg{
 8   width: 100%;
 9   height: 100%;
10 }
11 .square2{
12   padding-bottom:100%;
13   height: 0;
14   width: 50%;
15   position: relative;
16 }
17 .square2 .con{
18   position: absolute;
19   width: 100%;
20   height: 100%;
21   top:0;
22   left:0;
23 }
24 </style>

运行效果如下:


运行之后发现img写出来的图片如果是长方形的不能够像background一样显示居中,那么此时有一个属性就要起作用啦 “object-fit”

1 <style>
2 .squareimg{
3   width: 100%;
4   height: 100%;
5   -o-object-fit: cover;
6   object-fit: cover;
7 }
8 </style>

object-fit:
指定替换元素的内容应该如何适应到其使用的高度和宽度确定的,具体属性如下
/* 关键属性 */
object-fit: fill;
object-fit: contain;
object-fit: cover;
object-fit: none;
object-fit: sca

le-down;
/* 全局属性 */
object-fit: inherit;
object-fit: initial;
object-fit: unset;

具体用法推荐:
http://www.zhangxinxu.com/wordpress/2015/03/css3-object-position-object-fit/
https://developer.mozilla.org/zh-CN/docs/Web/CSS/object-fit

方法三:
还是img的形式,只不过在方法二的基础上拿掉了一层(class=“con”)的div,直接将图片绝对定位,具体代码如下

 1 <div class="square3"><img src="images/square.jpg" style="width:100%;" class="squareimg2"/></div>
 2 <style>
 3 .square3{
 4   padding-bottom:100%;
 5   height: 0;
 6   position: relative;
 7 }
 8 .squareimg2{
 9   position: absolute;
10   width: 100%;
11   height: 100%;
12   -o-object-fit: cover;
13   object-fit: cover;
14 }
15 </style>

以上是用padding-top/bottom实现的方法,其实用marign-top/bottom也是可以实现的,我简单了写了几个例子

方法一

 1 <div class="square1">
 2 <div class="con"></div>
 3 </div>
 4 <style>
 5 .square1{
 6   width:100%;
 7   overflow: hidden;/*是为了防止margin塌陷,触发BFC*/
 8   background: #ccc;
 9 }
10 .con{
11   width: 100%;
12   margin-top:100%;/*margin-bottom:100%*/
13 }
14 </style>

此方法在正方形内部写内容时候还是会有溢出的问题,但是用行内样式style:backgound的方式写图片是没问题的


方法二:

 1 <div class="square2">
 2 <div class="con2">
 3 <img src="images/square.jpg" class="img"/>
 4 </div>
 5 </div>
 6 <style>
 7 .square2{
 8   width: 100%;
 9   position: relative;
10   overflow: hidden;/*是为了防止margin塌陷,触发BFC*/
11 }
12 .con2{
13   width: 100%;
14   margin-bottom: 100%;
15   height: 0;
16 }
17 
18 .img{
19   width: 100%;
20   height: 100%;
21   position: absolute;
22   z-index: 0;
23   top: 0;/*margin-top:100%必须添加top值*/
24   left: 0;/*margin-top:100%必须添加left值*/
25 }
26 </style>

如果想在正方形中写入文子内容,将img换成html中其他标签即可。

方法三
利用伪元素

 1 <div class="square3">
 2 伪元素
 3 </div>
 4 
 5 <div class="square3">
 6 <!-- 利用绝对定位 class="con" 的 div-->
 7 <div class="con">伪元素</div>
 8 </div>
 9 <style>
10 .square3 {
11   width: 100%;
12   overflow: hidden;
13   background: #ccc;
14 }
15 .square3:after {
16   content: '';
17   display: block;
18   margin-top: 100%; /* margin 百分比相对父元素宽度计算 */
19 }
20 .con{
21   width: 100%;
22   height: 100%;
23   position: absolute;
24 }
25 </style>

想要用伪元素的方式在正方形中写入文字等内容,需要写一个独立的块然后利用绝对定位消除空间占用。

以上就是我能想到的一些方法,如果有什么错误的地方还请各位大侠不吝赐教。

综合上面的方法,我写了一个简单的列表demo

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  5 <meta name="keywords" content=""/>
  6 <meta name="description" content=""/>
  7 <meta name="viewport"
  8 content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
  9 <meta name="apple-mobile-web-app-capable" content="yes"/>
 10 <meta content="telephone=no" name="format-detection"/>
 11 <meta name="apple-mobile-web-app-status-bar-style" content="default"/>
 12 <meta http-equiv="Pragram" content="no-cache">
 13 <meta http-equiv="Cache-Control" content="no-cache">
 14 <meta http-equiv="Expires" content="0">
 15 </head>
 16 <title>例子</title>
 17 <style>
 18 html {
 19   background-color: #ffffff;
 20   font-size: 14px;
 21   -ms-text-size-adjust: 100%;
 22   -webkit-text-size-adjust: 100%;
 23   font-weight: normal;
 24   overflow: auto;
 25 }
 26 
 27 body {
 28   font-size: 14px;
 29   font-family: 微软雅黑;
 30 }
 31 
 32 @media only screen and (min-width: 768px) {
 33 body {
 34   width: 768px;
 35   margin: 0 auto
 36 }
 37 }
 38 
 39 * {
 40   padding: 0;
 41   margin: 0;
 42 }
 43 
 44 .content {
 45   padding: 10px;
 46   overflow: hidden;
 47 
 48 }
 49 
 50 .content .item {
 51   float: left;
 52   margin-left: 10px;
 53   width: calc(50% - 5px);
 54   overflow: hidden;
 55   position: relative;
 56 }
 57 
 58 .content .item:nth-child(odd) {
 59   margin-left: 0
 60 }
 61 
 62 .content .top {
 63   width: 100%;
 64   padding-bottom: 100%;
 65   height: 0;
 66 }
 67 
 68 .content .txt {
 69   padding: 5px;
 70 }
 71 
 72 </style>
 73 </head>
 74 <body>
 75 <ul class="content">
 76 <li class="item">
 77 <div class="top" style="background: url(images/square.jpg)no-repeat center /cover"></div>
 78 <p class="txt">
 79 文字文字文字文字文字文字文字文字
 80 </p>
 81 </li>
 82 <li class="item">
 83 <div class="top" style="background: url(images/square.jpg)no-repeat center /cover"></div>
 84 <p class="txt">
 85 文字文字文字文字文字文字文字文字
 86 </p>
 87 </li>
 88 <li class="item">
 89 <div class="top" style="background: url(images/square.jpg)no-repeat center /cover"></div>
 90 <p class="txt">
 91 文字文字文字文字文字文字文字文字
 92 </p>
 93 </li>
 94 <li class="item">
 95 <div class="top" style="background: url(images/square.jpg)no-repeat center /cover"></div>
 96 <p class="txt">
 97 文字文字文字文字文字文字文字文字
 98 </p>
 99 </li>
100 </ul>
101 </body>
102 </html>
Demo Code
posted @ 2021-03-23 18:13  王小道  阅读(542)  评论(0编辑  收藏  举报