纯CSS实现自适应正方形的几种方式
在写页面布局时候正方形对我们来说应该很常见,比如商品列表展示,头像展示, 在微博上发布图片的展现等
正方形用固定的形式写很简单 直接长=宽写固定的值如下
<div class="square"></div>
.square{
width:200px;
height:200px;
background:#ccc;
}
这样写没有问题,但是如果想在移动端实现宽度自适应呢,利用javascript会不会有点太麻烦啦,确实很麻烦啦,那么就让我们用纯CSS的方式来实现一下
方法一:
利用.CSS3 vw 单位,vw是相对于视口的宽度。视口被均分为100单位的vw。1vw = 1% viewport width
<div class="square">hello,viewport</div>
<style>
.square {
width: 50%;
height: 50vw;
background: #ccc;
}
</style>
方法二:
设置垂直方向的padding撑开容器(padding可以用百分比,百分比是根据它包含块的width来确定的,也就是父级元素的width)
<div class="square2"></div>
<style>
.square2{
width: 50%;
padding-bottom:100%;
height:0;
}
</style>
在这里需要注意一下,如果不写hegith的话,正方形内文字会溢出,溢出的高度正好就是文字所占空间的高度。
有的人肯定会想padding-bottom换成padding-top可以吗,那我们就来试试
<div class="square2"></div>
<style>
.square3{
width: 50%;
padding-top:100%;
height:0;
}
</style>
可以看出来在正方形中有内容的时候,内容会在正方形外面,这是因为默认文字是从左到右,从上到下的排列所以paddin-top以后文字会在正方形外面,如果就想用padding-top来写那么请看方法三
方法三:
利用双层嵌套来写,将外层的div的position设置relative,内层的position设置为absoult,利用绝对定位消除空间占用
分别看设置成padding-top/padding-bottom的效果
<div class="square3">
<div class="con">
内容
</div>
</div>
<div class="square3-2">
<div class="con">
内容
</div>
</div>
<style>
.square3{
padding-bottom:100%;
height: 0;
background:#ccc;
width: 50%;
position: relative;
}
.square3-2{
padding-top:100%;
height: 0;
background:#ccc;
width: 50%;
position: relative;
}
.con{
position: absolute;
width: 100%;
height: 100%;
}
</style>
运行之后我们发现写padding-top还是不可以,我们来检查代码发现,在写内层的div时候没有给top,left的值,让我们把top,left加上再看看
<style>
.con{
position: absolute;
width: 100%;
height: 100%;
top:0;
left:0;
}
</style>
所以如果用padding-top的时候一定要记得添加top,left
还可以利用伪元素
<div class="square4">
伪元素
</div>
<div class="square4">
<!-- 利用绝对定位 -->
<div class="con">伪元素</div>
</div>
<style>
.square4 {
width: 100%;
background: #ccc;
}
.square4:after {
content: '';
display: block;
padding-top: 100%;
}
.con{
width: 100%;
height: 100%;
position: absolute;
}
</style>
其实我们平时再用到正方形的时候比较多的情况是图片,让图片正方形且自适应,下面也列出了几种方法
方法一:
通过style:background的方式写在标签内部
<div class="square1" style="background: url(images/square.jpg)no-repeat center /cover"></div>
<style>
.square1{
width: 50%;
padding-top:100%;/*padding-bottom:100%也可以*/
height: 0; /*可不写*/
}
</style>
这里写padding-top/bottom 都可以,height也可以不写高度运行效果如下:
方法二:
用img的是形式
<div class="square2">
<div class="con">
<img src="images/square.jpg" class="squareimg"/>
</div>
</div>
<style>
.squareimg{
width: 100%;
height: 100%;
}
.square2{
padding-bottom:100%;
height: 0;
width: 50%;
position: relative;
}
.square2 .con{
position: absolute;
width: 100%;
height: 100%;
top:0;
left:0;
}
</style>
运行效果如下:
运行之后发现img写出来的图片如果是长方形的不能够像background一样显示居中,那么此时有一个属性就要起作用啦 “object-fit”
<style>
.squareimg{
width: 100%;
height: 100%;
-o-object-fit: cover;
object-fit: cover;
}
</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,直接将图片绝对定位,具体代码如下
<div class="square3"><img src="images/square.jpg" style="width:100%;" class="squareimg2"/></div>
<style>
.square3{
padding-bottom:100%;
height: 0;
position: relative;
}
.squareimg2{
position: absolute;
width: 100%;
height: 100%;
-o-object-fit: cover;
object-fit: cover;
}
</style>
以上是用padding-top/bottom实现的方法,其实用marign-top/bottom也是可以实现的,我简单了写了几个例子
方法一
<div class="square1">
<div class="con"></div>
</div>
<style>
.square1{
width:100%;
overflow: hidden;/*是为了防止margin塌陷,触发BFC*/
background: #ccc;
}
.con{
width: 100%;
margin-top:100%;/*margin-bottom:100%*/
}
</style>
此方法在正方形内部写内容时候还是会有溢出的问题,但是用行内样式style:backgound的方式写图片是没问题的
方法二:
<div class="square2">
<div class="con2">
<img src="images/square.jpg" class="img"/>
</div>
</div>
<style>
.square2{
width: 100%;
position: relative;
overflow: hidden;/*是为了防止margin塌陷,触发BFC*/
}
.con2{
width: 100%;
margin-bottom: 100%;
height: 0;
}
.img{
width: 100%;
height: 100%;
position: absolute;
z-index: 0;
top: 0;/*margin-top:100%必须添加top值*/
left: 0;/*margin-top:100%必须添加left值*/
}
</style>
如果想在正方形中写入文子内容,将img换成html中其他标签即可。
方法三
利用伪元素
<div class="square3">
伪元素
</div>
<div class="square3">
<!-- 利用绝对定位 class="con" 的 div-->
<div class="con">伪元素</div>
</div>
<style>
.square3 {
width: 100%;
overflow: hidden;
background: #ccc;
}
.square3:after {
content: '';
display: block;
margin-top: 100%; /* margin 百分比相对父元素宽度计算 */
}
.con{
width: 100%;
height: 100%;
position: absolute;
}
</style>
想要用伪元素的方式在正方形中写入文字等内容,需要写一个独立的块然后利用绝对定位消除空间占用。
以上就是我能想到的一些方法,如果有什么错误的地方还请各位大侠不吝赐教。
综合上面的方法,我写了一个简单的列表demo
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="keywords" content=""/>
<meta name="description" content=""/>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta content="telephone=no" name="format-detection"/>
<meta name="apple-mobile-web-app-status-bar-style" content="default"/>
<meta http-equiv="Pragram" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0">
</head>
<title>例子</title>
<style>
html {
background-color: #ffffff;
font-size: 14px;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
font-weight: normal;
overflow: auto;
}
body {
font-size: 14px;
font-family: 微软雅黑;
}
@media only screen and (min-width: 768px) {
body {
width: 768px;
margin: 0 auto
}
}
* {
padding: 0;
margin: 0;
}
.content {
padding: 10px;
overflow: hidden;
}
.content .item {
float: left;
margin-left: 10px;
width: calc(50% - 5px);
overflow: hidden;
position: relative;
}
.content .item:nth-child(odd) {
margin-left: 0
}
.content .top {
width: 100%;
padding-bottom: 100%;
height: 0;
}
.content .txt {
padding: 5px;
}
</style>
</head>
<body>
<ul class="content">
<li class="item">
<div class="top" style="background: url(images/square.jpg)no-repeat center /cover"></div>
<p class="txt">
文字文字文字文字文字文字文字文字
</p>
</li>
<li class="item">
<div class="top" style="background: url(images/square.jpg)no-repeat center /cover"></div>
<p class="txt">
文字文字文字文字文字文字文字文字
</p>
</li>
<li class="item">
<div class="top" style="background: url(images/square.jpg)no-repeat center /cover"></div>
<p class="txt">
文字文字文字文字文字文字文字文字
</p>
</li>
<li class="item">
<div class="top" style="background: url(images/square.jpg)no-repeat center /cover"></div>
<p class="txt">
文字文字文字文字文字文字文字文字
</p>
</li>
</ul>
</body>
</html>