CSS常用技巧

555 阅读7分钟

hover产生遮罩

技巧:根据opacity透明度来实现遮罩

    .coverImg {
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
        cursor: default;
        text-align: center;
        color: #fff;
        opacity: 0;
        font-size: 20px;
        background-color: rgba(0, 0, 0, 0.3);
        transition: opacity 0.3s;
        z-index: 100;
    }
    .coverImg:hover {
        z-index: 100;
        opacity: 1;
    }

nth-child 和 nth-of-type

    .wrap p:nth-child(2)
    {
    background:#ff0000;
    }

规则从右向左理解: 上面代码表示class为wrap的父元素下面的子元素,第二个子元素是P标签的样式。如果第二个子元素不是P标签,是a标签那么样式不生效。

    .wrap :nth-child(2)
    {
    background:#ff0000;
    }

规则从右向左理解: 上面代码表示class为wrap的父元素下面的子元素,第二个子元素的样式。无论第二个元素是什么类型的元素(a标签、p标签、div都会生效,没有元素类型的限制)

    .wrap p:nth-of-type(2)
    {
    background:#ff0000;
    }

规则从左向右理解:上面这段代码的意思是class为wrap的父元素下面的子元素,所有是P元素的子元素中第二个的样式。这里的第几个子元素是有类型的限定的。

    .wrap :nth-of-type(2)
    {
    background:#ff0000;
    }

规则从左向右理解:上面这段代码的意思是class为wrap的父元素下面的子元素,所有类型子元素中第二个的样式,比如p元素的第二个、span元素的第二个、h1元素的第二个等等。 blog.csdn.net/Calarqiang/…

display:inline-block;

inline-block元素垂直居中

子元素设置: vertical-align: middle;
父元素设置: line-height: height;

  .inner-wrap{
    line-height: 220rpx;
    height: 220rpx;
    width: 400rpx;
    overflow: hidden;
    white-space: nowrap;
    font-size: 0;
    /* border: 1rpx solid black; */
    position: relative;
    background-color: red;
  }
  
  .item1{
    vertical-align: middle;
    height: 90rpx;
    width: 90rpx;
    border-radius: 50%;
    background-color: white;
    display: inline-block;
    margin-right: 30rpx;
  }

  .item2{
    height: 50rpx;
    width: 50rpx;
    vertical-align: middle;
    border-radius: 50%;
    background-color: white;
    display: inline-block;
    margin-right: 30rpx;
  }  


参考:www.cnblogs.com/leona-d/p/1…

inline-block元素去除水平直接的间隙

产生间隙的原因是:inline-block元素直接的空格、换行产生的。

解决方法:设置父元素 font-size:0;

参考:blog.csdn.net/gladys_1111…

正方形

width: 25%; 意味着元素的宽度是父元素宽度的25%;
padding-bottom: 25%; 意味着这个元素的padding-bottom的距离是父元素宽度的25%;
这样就可以巧妙的形成一个正方形: 可以看到这么形成的正方形如果里面有内容是有问题的,所以要给height:0;这样才能形成一个正方形。 这样才可以形成一个完美的正方形。
技巧:
margin: %;
padding: %;
其实都是相对于父元素宽度的百分比!

标题上下加引号

vertical-align设置的是 display:inline-block;元素 的垂直排布方式

	<style>
        .txt{
            padding-top: 15px; //上下相差 5 - 20
            background-color: orange;
            color: white;
            width: 500px;
            font-size: 32px;
            font-family:"Times New Roman",Georgia,Serif;
            text-align: center;
        }
        .sub-top{
            vertical-align: 5px;
        }
        .sub-bottom{
            vertical-align: -20px;
        }
    </style>
    
<p class="txt">
    <span class="sub-top"></span>
    <span>如何书写带引号的标题</span>
    <span class="sub-bottom"></span>
</p>

display:none; visibility: hidden; opacity:0;

我们知道让元素隐藏的3种方法:

  • display:none;
  • visibility: hidden;
  • opacity:0;

这里介绍一下这三种方法的特点:

display:none;

  1. display:none;的元素页面不占据空间;
  2. 父元素如果是 display:none;子元素设置 display:block;不会显示。页面根本没有父元素,怎么会出现子元素呢?即父元素影响子元素的显示。
  3. display:none;的元素 绑定了click事件无效。因为页面根本没有这个元素。
  4. 改变display样式会引发页面的回流。

visibility: hidden;

  1. visibility: hidden; 的元素是会占据页面空间,只是没有显示在页面而已;
  2. 父元素是 visibility: hidden; 子元素 visibility: visible; 子元素会显示在页面上。子元素本身会继承父元素visibility: hidden;不显示。但是如果强制子元素显示也是可以的。父元素并不能决定子元素不显示。
  3. 父元素是 visibility: hidden; 绑定的事件,点击父元素并不会触发;但是visibility: visible;的子元素却可以冒泡触发父元素 绑定的事件。 4.改变visibility会触发重绘,不会引发回流。

opacity:0;

  1. opacity:0; 的元素会占据页面空间,只是没有显示在页面;
  2. 父元素设置了opacity:0; 子元素设置 opacity:1; 也没有用。因为 opacity 属性具有继承性,设置子元素 opacity:1; 也是在父元素的 opacity 的基础上的 1;
  3. opacity:0; 毕竟只是透明度为0。绑定的事件是可以触发的。
  4. 改变opacity会触发重绘,不会引发回流。

上面结论请看下面的例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>display-visibility-opacity</title>
    <style>
        div{
            margin: 10px 0;
        }
        .display-wrap{
            width: 300px;
            height: 300px;
            background-color: red;
            /*display: none;*/
        }
        .dis-inner{
            width: 100px;
            height: 100px;
            background-color: gray;
        }
        .vis-wrap{
            width: 300px;
            height: 300px;
            background-color: red;
            visibility: hidden;
        }
        .vis-inner{
            width: 100px;
            height: 100px;
            background-color: gray;
            visibility: visible;
        }
        .opa-wrap{
            width: 300px;
            height: 300px;
            background-color: red;
            opacity: 0;
        }
        .opa-inner{
            width: 100px;
            height: 100px;
            background-color: gray;
            opacity: 1;
        }
    </style>
</head>
<body>
    <div>
        <button id="btn1">display change</button>
    </div>
    <div class="display-wrap" id="disWrap">
        <div class="dis-inner"></div>
    </div>

    <div>
        <button id="btn2">visibility change</button>
    </div>

    <div class="vis-wrap" id="visWrap">
        <div class="vis-inner"></div>
    </div>

    <div>
        <button id="btn3">opacity change</button>
    </div>

    <div class="opa-wrap" id="opaWrap">
        <div class="opa-inner"></div>
    </div>
    <p>我是最后</p>
    <script>
        document.getElementById('btn1').onclick = function(){
            document.getElementsByClassName('display-wrap')[0].style.display = 'none';
        }

        document.getElementById('btn2').onclick = function(){
            document.getElementsByClassName('vis-wrap')[0].style.visibility = 'visible';
        }

        document.getElementById('btn3').onclick = function(){
            document.getElementsByClassName('opa-wrap')[0].style.opacity = '1';
        }

        document.getElementById('disWrap').onclick = function () {
            console.log('disWrap clicked');
        }

        document.getElementById('visWrap').onclick = function () {
            console.log('visWrap clicked');
        }

        document.getElementById('opaWrap').onclick = function () {
            console.log('opaWrap clicked');
        }
    </script>
</body>
</html>

参考:blog.csdn.net/xx_yan/arti… www.cnblogs.com/echolun/p/1…

搞懂BFC

从问题出发?

  1. 什么是外边距重叠margin_collapsing?
  2. 怎么触发形成BFC ?
  3. BFC的特性(价值)有哪些?

外边距重叠margin collapsing

常见的重叠margin collapsing有两种情况:

  1. 同一层相邻元素之间(同级相邻元素重叠)
<style>
    html *{
        padding:0;
        margin:0;
    }
    div{
        width: 200px;
        height: 200px;
    }
    .one{
        background-color: red;
        margin-bottom:20px;
  		//形成了BFC
        display: flow-root;
    }
    .two{
        background-color: blue;
        margin-top:30px;
    }
</style>
<div>
    <div class="one"></div>
    <div class="two"></div>
</div>

可以看到上下两个div的margin并不是 20+30=50px,而是取了最大值 30px。这就产生了margin collapsing。

注意相邻元素的 margin collapsing 对于在同一个BFC块中也会产生。还有就是一个不是BFC,一个是BFC也会产生。两个都是BFC也会产生margin collapsing。

破解办法:

  • 使得两个元素不相邻,中间加一个其他元素;
  • margin只作用于其中某一个元素上面。
  1. 父子元素重叠
<style>
    .wrap{
        margin-top:50px;
        width:300px;
        height: 300px;
        background-color: red;
        /*padding-top:10px;*/
        /*border: 1px solid black;*/
        /*display: table;*/
        /*overflow: auto;*/
        /*position: absolute;*/
    }
    .inner{
        margin-top:100px;
        width:100px;
        height: 100px;
        background-color: blue;
    }
</style>
<div>
    <div class="wrap">
        <div class="inner"></div>
    </div>
</div>

参考:
developer.mozilla.org/zh-CN/docs/… www.cnblogs.com/nyw1983/p/1… 破解办法:

  • 使得两个元素不直接相邻:给父元素border/设置父元素的padding/
  • 使得父元素形成BFC:父元素display:inline-block/display:flow-root/... 下面会详细介绍怎么触发形成BFC。

怎么触发形成BFC

developer.mozilla.org/zh-CN/docs/…

  • 根元素(html)
  • 浮动元素(float: left 或 right)
  • 绝对定位元素(position:absolute 或 fixed )
  • 行内块元素(display: inline-block)
  • 表格单元格(display: table-cell)
  • 表格标题(display: table-caption)
  • 匿名表格单元格元素(元素的 display 为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot 的默认属性)或 inline-table)
  • overflow值不为默认值 visible
  • display值为flow-root
  • contain 值为 layout、content 或 paint 的元素
  • 弹性元素(display: flex 或 inline-flex)
  • 网格元素(display: grid 或 inline-grid)

BFC的特性

  1. 如上面介绍的BFC可以解决父元素、子元素margin collapsing(外边距重叠)的问题。
  2. 可以包含浮动元素
    <style>
        .wrap{
            background: #348EED;
            display: flow-root;
        }
        .float-left{
            float: left;
            width: 200px;
            height: 200px;
            background: #fcc;
        }
        .right{
            min-height: 100px;
            border: 5px solid black;
        }
    </style>
    <div class="wrap">
        <div class="float-left"></div>
        <div class="right"></div>
    </div>

3. 不和浮动元素重叠
上面例子中,右边的元素其实是跟浮动元素重叠了。为了使左右两边元素分开,可以让右边的元素成为一个BFC。

    <style>
        .wrap{
            background: #348EED;
            display: flow-root;
        }
        .float-left{
            float: left;
            width: 200px;
            height: 200px;
            background: #fcc;
        }
        .right{
            min-height: 100px;
            border: 5px solid black;
            display: flow-root;
        }
    </style>
    <div class="wrap">
        <div class="float-left"></div>
        <div class="right"></div>
    </div>

clear:both的原理

blog.csdn.net/Calarqiang/…

它的本质是给某个元素设置一个正的margin-top值。当一个元素上面有一个浮动元素时,浏览器会自动计算出该浮动元素的盒子占地大小(可见框+margin),然后给后面的那个被它盖住的元素设置该margin-top值,以此来清除浮动的影响!。

让hover更丝滑

有一个需求是正方形的图片hover的时候变成圆形。我们都知道直接hover样式就可以,但是效果做起来有点卡顿。这个时候使用 transition: all 0.3s ease-in-out; 可以让效果更丝滑。

<style>
    .img-wrap{
        width: 200px;
        height: 200px;
    }
    img{
        width: 200px;
        height: 200px;
        transition: all 0.3s ease-in-out;
    }
    img:hover{
        border-radius: 50%;
    }
</style>
<div class="img-wrap">
    <img src="images/1.jpg" alt="img01"/>
</div>

全屏

实现全屏的代码见博客: juejin.cn/post/690046…

现在一个场景的是:可视化的页面产品经理只想在全屏状态下正好铺满视图,非全屏状态的时候要出现滚动条,不要挤到一起。

<style>
    *{
        padding: 0;
        margin: 0;
    }
    .header{
        height: 100px;
    }
    .content{
        height: calc(100vh - 100px);
        background-color: red;
    }
</style>
<div>
    <div class="header">
        <span>欢迎光临我的掘金</span>
        <button id="fullBtn">全屏</button>
    </div>
    <div class="content"></div>
</div>

单纯设置 height: calc(100vh - 100px); 可以满足全屏的时候正好一屏幕。但是在非全屏状态下 content 部分如果内容比较多的话会挤压在一起,尤其对于图表类的非常不友好。这个时候,我们可以使用 min-height 设置一个最小高度,这样下面的容器就不会挤到一起,同时,还满足了全屏下只显示一屏的需求。

<style>
    *{
        padding: 0;
        margin: 0;
    }
    .header{
        height: 100px;
    }
    .content{
        height: calc(100vh - 100px);
        /* 新增,保证在非全屏下不会挤到一起 */
        min-height: 580px;
        background-color: red;
    }
</style>