zoukankan      html  css  js  c++  java
  • 【CSS黑科技2】CSS百分比实现高度占位自适应(margin/padding)

    | 导语 在很多场景下,我们都需要给容器设定宽高比,实现自适应占位,巧用margin/padding可以让我们实现我们的需求

     

    基本知识点

    本文依赖于一个基础却又容易混淆的css知识点:当padding/margin取形式为百分比的值时,无论是left/right,还是top/bottom,都是以父元素的width为参照物的!

    哈,top/left以父元素的width为参照物还好理解,但top/bottom不是以height更符合我们的预期吗?有疑惑很简单,看官方解释

     

     

    举个栗子

    我们有个页面,如下图,如果是在PC端好办,容器的宽高都写死是多少px,这样即使图片加载不出来容器都不会变型。但是在移动端,由于各机型分辨率相差太大,写死px是绝对不可能的,终究还得靠百分比来实现的:

     

    1. 一行2列的容器宽度设个50%吧,这样一行放俩容器,各占屏幕宽度一半,没问题。
    2. 图片宽度设个100%取容器的宽度,没问题。
    3. 容器高度没法设置啊,因为容器宽高的参照物不一样,而且需求是高度与宽度一致,所以无法通过为容器高度设置百分比来达成,那就只能靠内容高度撑开了。
    4. 容器的内容高度就是图片的高度,若图片是正方形,则图片高度与图片宽度一致,也即与容器宽度一致,看起来没问题是吧?实际上,在浏览器把图片加载出来以前,图片的高度是零,那可就没办法把容器撑开了,如下图所示:

     

    这样一来,即使图片加载速度再快,也会有个高度撑开的过程,如果图片没有加载成功,那更惨,整个页面的结构都有可能会有问题,这肯定会被测试同学报bug的啦

    现在问题很明显了,就是怎么不用图片可以撑开容器高度,而且是高度可控,比如宽高比是个1:2什么的

    给容器设置padding-top/bottom

    啦啦啦,上文说的padding-top/bottom的百分比值,是依赖父容器宽度的,这样容器的宽度和高度都可以统一同一个参照物了(父元素的宽度)

    举个例子,图片宽高比是1:1,一行放2个容器

    视觉结果如下:

     

    容器的盒子模型如下:

     

    从盒子模型可以看出,虽然容器的内容高度为0,但由于有了跟内容宽度一致的padding,因此整体视觉效果上像是被撑开了。我们达成了最初的梦想

    此方案浏览器兼容性很不错,唯一的缺陷是无法给容器设置max-height属性了,因为max-height只能限制内容高度,而不能限制padding!!,如下这个项目:

     

    这个头图是按宽高比设置的大小,但是还需要考虑横屏的情况,如下图:

     

    我们是不会轻易的狗带的!!

    给子元素/伪元素设置margin/padding撑开容器

    从上面的方案的盒模型看出max-height失效的原因是容器的高度本来就是padding撑的,而内容高度为0,max-height无法起作用。那想要优化这一点,唯一的方法就是利用内容高度来撑开而非padding,这个方案跟消除浮动所用的方案非常相似:给容器添加一个子元素/伪元素,并把子元素/伪元素的pading/margin设为100%,使其实际高度相当于容器的宽度,如此一来,便能把容器的高度撑至与宽度达成我们预想的宽高比(1:1)了。由于添加子元素与HTML语义化相悖,因此更推荐使用伪元素:after来实现此方案。

    我们再来看看此时的盒子模型:

     

    完美,可以看出,此时容器的内容高度与内容宽度一致,妈妈再也不用担心我无法通过max-height来限制容器高度了。

    上面那个项目也是这样解决了不能设置max-height的痛点

     

     

    另外,使用margin的话需要考虑margin折叠的问题(参考代码BFC相关),padding则无此烦恼。

    哈,容器就给你了,要往容器内添加内容,但不能添加额外高度,那只能是使用position:absolute啦~

    最后,奉上sass如下:

    //占位 是否可控高度:false(无法控制min-height,但没有多余结构) true(可控制min-height,但要增加结构)
    @mixin proporBox($arg:1, $type:false, $ele:':before'){
        position: relative;
        @if $type == true {
            &#{$ele}{
                content: '';
                display: block;
                width: 100%;
                padding-top: percentage($arg);
            }
        }@else{
            padding-top: percentage($arg);
        }   
    }
  • 相关阅读:
    Hibernate save, saveOrUpdate, persist, merge, update 区别
    Eclipse下maven使用嵌入式(Embedded)Neo4j创建Hello World项目
    Neo4j批量插入(Batch Insertion)
    嵌入式(Embedded)Neo4j数据库访问方法
    Neo4j 查询已经创建的索引与约束
    Neo4j 两种索引Legacy Index与Schema Index区别
    spring data jpa hibernate jpa 三者之间的关系
    maven web project打包为war包,目录结构的变化
    创建一个maven web project
    Linux下部署solrCloud
  • 原文地址:https://www.cnblogs.com/cuoreqzt/p/5848270.html
Copyright © 2011-2022 走看看