1. 程式人生 > 其它 >CSS自定義屬性在元件開發中的使用

CSS自定義屬性在元件開發中的使用

目錄

技術概述

自定義屬性的概述(技術為何)

  • 自定義屬性:由--開頭的自命名屬性稱為自定義屬性,同時可以給自定義屬性賦予任何值。比如 --color: #000
  • 變數:CSS的 var() 函式引用的自定義屬性被稱為變數。var() 會返回自定義屬性所對應的值,同時可以被運用於相應的CSS屬性。對應的即是CSS規則中的屬性值。

自定義屬性的作用(為何使用)

由於專案中含有過多的CSS檔案會增加了維護成本

  • 使用CSS自定義屬性使得大檔案更易於閱讀,只需要在自定義屬性處修改一次,這個修改就會應用到使用該自定義屬性的任何地方。
  • CSS自定義屬性具有較強的語義化。這些語義化資訊讓你的CSS檔案變得易讀和理解。比如(--primary-color
  • 到目前為止所有的現代瀏覽器中都對CSS自定義屬性做了良好的支援,這將使得原生CSS從此變得更加強大。(相容問題不再頭疼)

技術詳述

自定義屬性的使用

  • 獲取自定義屬性的屬性值。
    方法:使用var()方法就能實現:
    第一步:宣告

    :root {//這裡的:root 涉及到一個級聯問題,下面會提到
        --color: red;
    }
    

    第二步:取值

    .btn {
        background-color: var(--color);
    }
    

    如此一來,在ClassNamebtn

    的元件的背景色就會設定為red,而要修改是隻需要修改自定義屬性color的值即可。
    補充:

    • 預設值
      若開發者並沒有定義過--color這個變數時,那麼在使用時可以通過給var()函式傳遞一個引數作為預設值。
      .btn {
          background-color: var(--color, blue);//即沒有值時預設為藍色
      }
      
    • 級聯、作用域
      在什麼時候又或是在哪裡定義這些自定義屬性的問題涉及到級聯及作用域。
      ①當希望將--color設定為全域性變數時,最簡單的方法是使用 :root 偽元素;
      ②當希望在不同的模組使用不同的--color值時,只需要在模組的作用域中給屬性重新宣告並賦值。
  • CSS計算用到的calc() 函式,常常被用於跨單位的計算,calc()與自定義屬性結合使用也是十分方便的。

    :root{
        --all-height:667px;
    }
    
    .myList {
        min-height: calc(var(--all-height) - 88.5px - 60px);
    }
    
  • js獲取自定義屬性
    自定義屬性也可以通過 getPropertyValuesetProperty 方法操作進行動態操作。

    const roots = getComputedStyle(document.querySelector(':root'));
    
    const Color = roots.getPropertyValue('--color');//獲取自定義屬性值
    
    root.style.setProperty('--color', 'blue');//設定自定義屬性值
    

在本次專案alpha版本中的一個應用以及流程圖

例子:修改主題色

  • index.css檔案中宣告
    :root {
        --color: rgb(108,99,255);//預設顏色
    }
    
  • 使用
    //初始化所有可選主題色
    //state = {
    //    value: 0,
    //};
    const {value} = this.state 
    const data = [
        { value: 0, label: '基礎紫', color: 'rgb(108,99,255)' },
        { value: 1, label: '海天藍', color: 'rgb(15,136,253)' },
        { value: 2, label: '健康綠', color: 'rgb(30,154,143)' },
        { value: 3, label: '活力紅', color: 'rgb(224,56,55)' },
        { value: 4, label: '櫻花粉', color: 'rgb(255,92,124)' }
    ];
    
    //構造主題色選擇元件
    <List className={theme.checkbox}>
        {data.map(i => (
            <RadioItem key={i.value} checked={value === i.value} onChange={() => this.onChange(i.value)}>
                {i.label}
                <span style={{backgroundColor: i.color}} className={theme.show_color}></span>
            </RadioItem>
        ))}
    </List>
    
    //切換主題色函式
    onChange = (value) => {
        const root = document.querySelector(':root');
        let color = 'rgb(108,99,255)'
        localStorage.setItem('themeValue', value);
        switch(value) {
            case 1:
                color = 'rgb(15,136,253)'
                break
            case 2:
                color = 'rgb(30,154,143)'
                break
            case 3:
                color = 'rgb(224,56,55)'
                break
            case 4:
                color = 'rgb(255,92,124)'
                break
            default: 
                color = 'rgb(108,99,255)'
                break
        }
        root.style.setProperty('--color', color)//修改自定義屬性的值
        this.setState({
            value,
        });
    };
    
    //一處使用自定義主題色屬性的地方:導航欄
    <NavBar
        mode="light"
        rightContent={[
                <i style={{fontSize:"30px",color:"var(--color)"}} className="iconfont icon-help" onClick = {this.navbarImg_Click}></i>                   
        ]}
        className={NoticeCSS.NoticeNavbar}>
    
            <div style={{color:"var(--color)"}}>
            消 息
            </div>    
    </NavBar>
    
    流程圖

遇到的問題

自定義屬性的使用還是相對簡單的,所以仔細一點應該不會踩坑

  • 坑1:大小寫敏感
    css自定義屬性是大小寫敏感的,所以在命名時一定要注意,避免犯這種低階錯誤。
  • 坑2:未定義即使用
    因粗心忘記宣告自定義屬性即使用還有一個解決辦法就是以上提到的,在使用的儘量都給var()函式傳入一個預設值。
  • 坑3:在使用自定義屬性時應在正確的位置宣告,在不同的作用域內可定義不同值的同名自定義屬性。

總結

  • 自定義屬性的使用能夠減少對class的操作,我們在編寫時也能夠對具有一樣屬性值的元件統一操作,而不用去對class進行變化。
  • 降低了開發者定位 bug 的難度,讓樣式和行為分離。我們在查詢一處bug時通過改動自定義屬性也能快速更改類似bug。
  • 樣式和邏輯分別獨立,樣式只由CSS實現,變換邏輯只由JS來完成,不僅維護也更加容易,在需求變換時需要修改的東西也相對減少。

參考

CSS 自定義屬性:基礎篇