1. CSS 中的簡寫到底有多少坑?以后不敢了...

        共 4962字,需瀏覽 10分鐘

         ·

        2022-05-17 13:36

        點(diǎn)擊上方?前端陽光,關(guān)注公眾號

        回復(fù)加群,加入技術(shù)交流群交流群

        大家好,我是陽光,簡寫(語法糖)可能給我們編碼帶來了很多便利,但簡寫也會帶來一些問題,今天來討論一下 CSS 中的簡寫的"愛恨情仇"

        為什么說是愛恨情仇呢?因?yàn)楹唽懡o我們帶來了很多的便利,但凡事都有好有壞,你不能說簡寫一點(diǎn)壞處都沒有。所以我們就聊聊簡寫的?"好"?和?"壞"

        background

        這個 CSS 屬性大家肯定是再熟悉不過了,給元素設(shè)置背景色

        是這樣?

        .demo?{
        ??background:?#333;
        }

        還是這樣?

        .demo?{
        ??background-color:?#333;
        }

        應(yīng)該都有吧,換作我自己,平常這兩者用哪個好像也是看心情,如果你說肯定用前者啊,因?yàn)榍罢呔鸵粋€單詞,那其實(shí)后者也不麻煩,現(xiàn)在大家都用編輯器,在智能提示的輔佐下輸入?bgc?再按回車就能打出?background:?;?了,其實(shí)也不麻煩

        bgc

        回到正題,其實(shí)這兩者寫法我更推薦后者,為什么?來看個例子??

        <style>
        ??.demo?{
        ????background:?#333;??/*?給元素設(shè)置了背景色#333?*/
        ??}
        ??
        ??/*?...?中間隔了很多樣式代碼?*/

        ??.demo:hover?{
        ????background:?url("example.png");?
        ??}
        style>

        <div?class="demo"/>

        這個場景很簡單:鼠標(biāo)移到元素上就展示某張照片,未加載前用一個純色占位

        然而實(shí)際效果是?

        效果不盡人意

        為了效果明顯,我加了邊框、文字,網(wǎng)速調(diào)成?slow 3G

        可以看到?hover?時的?background?覆蓋掉了前者的?background,使得效果差強(qiáng)人意

        是因?yàn)榍罢吆秃笳叨际?background,所以后者自然會覆蓋前者嗎?不全是

        即便我們前者用的?background-color: #333;,也仍然會被后者覆蓋

        大家都知道?background?是一個語法糖,即很多屬性的簡寫 ??

        那像例子中用?background: url('example.png')時,做了什么呢?

        如上圖所示,它默認(rèn)把所有值都設(shè)置成了?initial,因此無論之前用到了其中哪個值都會被覆蓋,雖然?initial?設(shè)置了跟沒設(shè)置是一樣,都表示保持元素該屬性的初始值

        會不會有人想說:我一直都這么用的,都沒遇到啥問題?。?/span>

        我只想說一句:可能運(yùn)氣比較好,等代碼比較復(fù)雜了,你可能會回來補(bǔ)這個窟窿的

        結(jié)論:這就是一個簡寫造成的隱患,大家能避免則避免

        margin

        又提了一個大家再熟悉不過的屬性?margin,這里面又有啥坑呢?沒啥坑,就是想介紹一下其它用法

        以下都是它的簡寫:

        • margin: 10px 20px 30px 40px
        • margin: 10px 20px 30px
        • margin: 10px

        這些簡寫確實(shí)幫我們省去了不少的代碼量

        讓我們投身到一個例子??中:現(xiàn)在我想讓我的元素水平居中,我想用?margin?來實(shí)現(xiàn)

        <style>
        ??.parent?{
        ????width:?300px;
        ????height:?300px;
        ????border:?1px?solid?black;
        ??}

        ??.child?{
        ????width:?100px;
        ????height:?100px;
        ????background-color:?red;
        ????margin:?auto;??/*?水平居中?*/
        ??}
        style>

        <div?class="parent">
        ??<div?class="child"/>
        div>

        效果如你所愿:

        但你使用?margin: auto?時有沒有那么一瞬間想過,前面是否設(shè)置過?margin-top?或?margin-bottom?呢?比如這樣:




        ??

        預(yù)期的效果是什么樣的?而此時的效果是什么樣的?

        預(yù)期的效果
        現(xiàn)在的效果

        可以看到,預(yù)期是想要既水平居中,又距離頂部?100px,而現(xiàn)在?margin-top?被覆蓋了

        其實(shí)你單純想實(shí)現(xiàn)水平居中完全沒必要用?margin: auto,因?yàn)槟惚疽馐遣幌肴バ薷捻敳亢偷撞康拈g距的,只是因?yàn)槟阌昧诉@個簡寫,不得不這么做

        不然試試另一個簡寫?讓你只處理水平的間距




        ??

        這樣同樣能實(shí)現(xiàn)我們想要的效果,且不會影響?margin-top?和?margin-bottom?的屬性

        那同理,有沒有能只影響豎直方向的?margin?的簡寫呢?當(dāng)然有,那就是?margin-block

        一起來看另一個例子??

        <style>
        ????.parent?{
        ??????position:?relative;
        ??????border:?1px?solid?black;
        ??????width:?300px;
        ??????height:?300px;
        ????}

        ????.child?{
        ??????position:?absolute;
        ??????top:?0;
        ??????bottom:?0;
        ??????left:?0;
        ??????right:?0;
        ??????width:?100px;
        ??????height:?100px;
        ??????margin:?auto;
        ??????background-color:?red;
        ????}
        style>

        <div?class="parent">
        ??<div?class="child"/>
        div>

        效果如下:

        這是一種對于非相對定位的垂直水平居中方法(記好了,面試官問你垂直水平居中的方法又多了一個),我是從 HTML 原生的?

        ?標(biāo)簽中了解到的(之前在12個可能你沒見過,但非常實(shí)用的 HTML 標(biāo)簽介紹過?標(biāo)簽)

        dialog的水平居中實(shí)現(xiàn)

        為什么要用這個例子呢,我就是想引申出這個知識點(diǎn),跟大家分享一下我最近看到的小?tips

        我們可以刪除?margin: auto,用上前面說的?margin-inline: auto?和?margin-block: auto

        結(jié)論margin?的簡寫不如?background?那么復(fù)雜,但使用上了?margin-inline?和?margin-block?也可以給自己降低心智負(fù)擔(dān)

        inset

        上面說了那么多簡寫帶來的隱患,要不再來說說簡寫帶來的好處?

        還是舉個例子??

        <style>
        ??.parent?{
        ????position:?relative;
        ????border:?3px?solid?blue;
        ????margin:?200px;
        ????width:?300px;
        ????height:?300px;
        ??}

        ??.child?{
        ????position:?absolute;
        ????top:?0;
        ????bottom:?0;
        ????left:?0;
        ????right:?0;
        ????background-color:?red;
        ??}
        style>

        <div?class="parent">
        ??<div?class="child"/>
        div>

        這段代碼大家應(yīng)該都很熟悉,我們給?.child?元素設(shè)置成了絕對定位,并賦予了以下屬性:

        • top: 0;
        • bottom: 0;
        • left: 0;
        • right: 0;

        然后元素就撐滿父元素了,達(dá)到了?width: 100%?+?height: 100%?的效果,那為啥不直接設(shè)置寬高都?100%?呢?只用設(shè)置兩個屬性

        ??? 不這么做的原因還是要回到?position?本身,當(dāng)一個元素脫離文檔流時,若未設(shè)置?top、bottom、left、right,默認(rèn)元素停留的位置就是其未脫離文檔流時的位置

        可能有點(diǎn)繞,直接上張圖

        可以看到,零一?這個元素在脫離文檔流后,仍然是停留在它處于文檔流時的位置,那此時如果給他設(shè)置寬高?100%?會是什么樣呢?

        漂亮,超出父元素了,雖然解決這個問題也很簡單,直接加一個?left: 0?即可但我們還有更簡單的方法,那就是用?inset?這個屬性

        其實(shí)?inset?就是?top、right、bottom、left?的簡寫,不知道為什么,我看過很多人的代碼,都沒用過這個屬性,所以也給大家安利一下

        語法跟?margin?類似,因此我們用它來簡化剛才的代碼




        ??

        這里為什么我又推薦大家用?inset?了呢?本質(zhì)是因?yàn)榇颂幬覀兇_實(shí)是需要同時設(shè)置上下左右四個值的,那為何不用?inset?呢?

        border

        ?? 天吶,受不了了!怎么全是平時常用到的屬性,有這么多坑嗎?

        其實(shí)?border?這個還好,還是建議用簡寫的哈,只不過有一個特殊的?case,想給大家分享一下,避免踩坑

        有這樣一個場景:一個元素本身沒有邊框,當(dāng)鼠標(biāo)移入時出現(xiàn)邊框,邊框從有到無要有過渡動畫;同時鼠標(biāo)移除,邊框消失,也伴隨有過渡動畫

        <style>
        ??.demo?{
        ????width:?100px;
        ????height:?100px;
        ????background-color:?lightblue;
        ????border:?none;
        ????box-sizing:?border-box;
        ????transition:?border?1s?linear;
        ??}

        ??.demo:hover?{
        ????border:?4px?solid?red
        ??}
        style>

        <div?class="demo"/>

        大部分人都會這么寫對不對?效果如何呢?可惜只成功了一半!

        為什么鼠標(biāo)移出時,border?的過渡動畫消失了?

        圖中可以看到,border: none?其實(shí)就是把?border-style?設(shè)置成了?none,大家都知道?transition?對于?border?的過渡動畫其實(shí)是針對?border-color?和?border-width?的,但如果?border-style?都沒有,那還怎么看得到過渡動畫呢?

        所以我們想要實(shí)現(xiàn)鼠標(biāo)移出時的過渡動畫,就不能用?border: none?這個簡寫了,那該怎么辦?

        我想到了一個思路,可能不是最完美的,但根本看不出瑕疵,大家可以借鑒一下:

        將元素的?border?初始狀態(tài)設(shè)置為?border: 0px solid transparent,這樣既保證了?border-style?的存在,又能保證邊框會從?4px?過渡到?0px,顏色也從??過渡到?

        效果如下:

        總結(jié)

        對于?「我們到底該如何使用簡寫?」?這個問題,我認(rèn)為:需要一次性設(shè)置簡寫屬性中全部或絕大部分屬性時,可以使用簡寫;反之,則不太應(yīng)該使用簡寫




        往期推薦


        優(yōu)秀文章匯總:https://github.com/Sunny-lucking/blog

        內(nèi)推:https://www.yuque.com/peigehang/kb

        技術(shù)交流群


        我組建了技術(shù)交流群,里面有很多?大佬,歡迎進(jìn)來交流、學(xué)習(xí)、共建?;貜?fù)?加群?即可。后臺回復(fù)「電子書」即可免費(fèi)獲取?27本?精選的前端電子書!回復(fù)內(nèi)推,可內(nèi)推各廠內(nèi)推碼



        ???“分享、點(diǎn)贊在看” 支持一波??


        瀏覽 60
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 樱桃 码一区二区三区 | 91精彩在线视频 | 婷婷乱伦视频 | 艹逼动态图片 | 色狠狠网 |