自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

CSS @scope 如何取代 BEM

開發(fā) 前端
在本文中,我們探討了將 BEM 風(fēng)格應(yīng)用程序重構(gòu)為使用 Chrome 瀏覽器中新推出的 @scope 功能的方法。我們介紹了 @scope 的工作原理,然后將一個簡單的頁面從 BEM 重構(gòu)為 @scope 。

前端工程師最常見且最具挑戰(zhàn)性的問題之一是 CSS 命名約定。隨著 Block Element Modifier(BEM)方法的流行,許多人習(xí)慣于按照一種可維護的模式組織他們的樣式。

即將在 Chrome 瀏覽器中實施的 @scope 允許在樣式表中對樣式進行塊級作用域劃分,從而進一步提高了 BEM 的性能。這將使樣式表更易于維護,同時對 CSS 級聯(lián)進行更嚴(yán)格的控制。

在這篇文章中,我們將展示如何在 Chrome 中使用 @scope 特性,以及如何使用它來替換前端項目中的 BEM。我們通過幾個例子進行講解,你可以在 GitHub 上的示例項目中查看并跟隨操作。

CSS @scope 是什么?

在即將發(fā)布的 Chrome 118 版本中,@scope 特性創(chuàng)建了 CSS 樣式的塊級作用域。這給了開發(fā)者對 CSS 樣式更多的控制權(quán),因為我們現(xiàn)在可以在 CSS 文件中直接為視圖的不同部分明確定義作用域。

請看下面的 HTML 示例:

<main className="sample-page">
    <h1>With Scope</h1>
    <section className="first-section">
        <p>some text</p>
        <p>
            some text and then a <a href="/">back link</a>
        </p>
    </section>
    <section className="second-section">
        <h2>Dog Picture</h2>
        <div>
            <p>second section paragraph text</p>
        </div>
        <img src={'./DOG_1.jpg'} alt="dog" />
    </section>
</main>

在此 HTML 中,我們可以使用以下方法對 second-section 樣式區(qū)域內(nèi)的元素進行樣式設(shè)置:

.second-section {
    display: flex;
    flex-direction: column;
    border: solid;
    padding: 40px;
    margin: 20px;
}
@scope (.second-section) {
    h2 {
        text-align: center;
    }
    img {
        max-width: 400px;
        max-height: 100%;
    }
    div {
        display: flex;
        justify-content: center;
        margin: 20px;
    }
    p {
        max-width: 200px;
        text-align: center;
        background-color: pink;
        color: forestgreen;
        padding: 10px;
        border-radius: 20px;
        font-size: 24px;
    }
}

使用 @scope 時,還可以創(chuàng)建一個 "甜甜圈 "作用域,為一組樣式及其中的元素定義起始和結(jié)束部分。使用上述相同的 HTML,甜甜圈作用域可以定義從 sample-page 的起始區(qū)域到 second-section 樣式區(qū)域的樣式:

/* donut scope */
@scope (.sample-page) to (.second-section) {
    p {
        font-size: 24px;
        background-color: forestgreen;
        color: pink;
        text-align: center;
        padding: 10px;
    }
    a {
        color: red;
        font-size: 28px;
        text-transform: uppercase;
    }
}

最棒的是,它的功能與使用 BEM 造型非常相似,但代碼量更少。

瀏覽器支持 CSS @scope

截至2023年10月2日,CSS @scope 還未正式發(fā)布,因此需要開啟實驗性網(wǎng)絡(luò)功能標(biāo)志來使用它。要做到這一點,首先在 Chrome 中打開一個標(biāo)簽頁,前往 chrome://flags/,然后搜索并啟用“實驗性網(wǎng)絡(luò)平臺功能”標(biāo)志:

什么是 BEM

BEM 是一種在HTML視圖中分組樣式的方式,可以輕松地進行導(dǎo)航。

考慮到一個大型 HTML 頁面有許多具有不同樣式的元素。在設(shè)置了幾個初始樣式名稱后,隨著頁面的擴展,要保持樣式就會變得很困難。BEM 試圖通過圍繞實際樣式來構(gòu)建樣式名來緩解這一問題。

block 是一個包含 HTML 元素??紤]一下類似這樣的 HTML。

<main className="sample-page">
    <h1 className="sample-page__title">With BEM</h1>
    <section className="sample-page__first-section">
        <p className="sample-page__first-section--first_line">
            some text
        </p>
        <p className="sample-page__first-section--second-line">
            some text and then a{' '}
            <a
                className="sample-page__first-section--second-line-link"
                href="/"
            >
                back link
            </a>
        </p>
    </section>
</main>

在此 HTML 中。

  • 塊 = sample-page 樣式就是 block 樣式,因為它包裹了一組元素。
  • 元素 = 在為 <h1> 元素設(shè)計樣式時,該元素被視為 element ,因此會在樣式名稱中添加額外的 __ ,從而創(chuàng)建 sample-page__title 。 sample-page__first-section 也是如此。

修改器 = 當(dāng)在 <section> 元素中為 <p> 元素設(shè)計樣式時,樣式名稱會多出一個 --first-line ,從而創(chuàng)建 sample-page__first-section--first-line ,所以:

  • 塊為 sample-page。
  • 元素是 first-section。
  • 修飾詞是 first-line。

BEM 的擴展性很好,尤其是在使用 SASS 將樣式分組并使用 & 操作符創(chuàng)建類似內(nèi)容時:

.sample-page {
    display: flex;
    flex-direction: column;
    margin-top: 10px;

    &__title {
        font-size: 48px;
        color: forestgreen;
    }

    &__first-section {
      font-size: 24px;
      border: solid;
      padding: 40px;
      margin: 20px;

      &--first-line{
        font-size: 24px;
        background-color: forestgreen;
        color: pink;
        text-align: center;
        padding: 10px;
      }
    }
}

難點在于,在一個大型項目中,這會產(chǎn)生非常大的 CSS 或 SASS 文件,而這些文件仍然很難進行大規(guī)模管理??梢允褂?nbsp;@scope 替換 BEM 樣式,使樣式定義更小、更易于管理。

使用@scope重構(gòu)BEM

展示使用 @scope 的優(yōu)勢的最佳方式是在使用 React 等主流框架或庫的應(yīng)用程序中使用 @scope。在 GitHub 上的示例應(yīng)用程序中, react-example 文件夾中有一個項目,其中的頁面首先使用 BEM 進行了樣式設(shè)計,然后使用 @scope 進行了重構(gòu)。

可以運行應(yīng)用程序并單擊 WithBEM 或 WithScope 按鈕來查看具體實現(xiàn)。組件和樣式表都有相應(yīng)的名稱,前綴為 WithBEM 或 WithScope ,分別位于 pages 和 styles 文件夾中。

從 BEM 樣式組件 WithBEMPage.tsx 開始,我們首先看到了用 BEM 方法設(shè)計的 HTML 樣式:

<main className="sample-page">
    <h1 className="sample-page__title">With BEM</h1>
    <section className="sample-page__first-section">
        <p className="sample-page__first-section--first_line">
            some text
        </p>
        <p className="sample-page__first-section--second-line">
            some text and then a{' '}
            <a
                className="sample-page__first-section--second-line-link"
                href="/"
            >
                back link
            </a>
        </p>
    </section>
    <section className="sample-page__second-section">
        <h2 className="sample-page__second-section--title">
            Dog Picture
        </h2>
        <div className="sample-page__second-section--div">
            <p className="sample-page__second-section--div-paragraph">
                second section paragraph text
            </p>
        </div>
        <img
            className="sample-page__second-section--image"
            src={'./DOG_1.jpg'}
            alt="dog"
        />
    </section>
</main>

在組件 WithScopePage.tsx 中,我們可以通過以下內(nèi)容看到重構(gòu)是多么干凈利落:

<main className="sample-page">
    <h1>With Scope</h1>
    <section className="first-section">
        <p>some text</p>
        <p>
            some text and then a <a href="/">back link</a>
        </p>
    </section>
    <section className="second-section">
        <h2>Dog Picture</h2>
        <div>
            <p>second section paragraph text</p>
        </div>
        <img src={'./DOG_1.jpg'} alt="dog" />
    </section>
</main>

要將 BEM 重構(gòu)為 @scope ,只需找到樣式組,然后適當(dāng)添加您的作用域樣式。我們先來看看標(biāo)題部分。在原始的 WithBEMPage.tsx 文件中,每個部分都定義了不同的樣式。而在 @scope 版本中,則為特定元素定義了更簡潔的樣式:

.sample-page {
    display: flex;
    flex-direction: column;
    margin-top: 10px;
}
/* replaced */
/* .sample-page__title {
    font-size: 48px;
    color: forestgreen;
} */
/* donut scope */
@scope (.sample-page) to (.first-section) {
    h1 {
        font-size: 48px;
        color: forestgreen;
    }
}

同樣,在第一部分內(nèi)容中,原始 BEM 風(fēng)格如下:

.sample-page__first-section {
    font-size: 24px;
    border: solid;
    padding: 40px;
    margin: 20px;
}
.sample-page__first-section--first_line {
    font-size: 24px;
    background-color: forestgreen;
    color: pink;
    text-align: center;
    padding: 10px;
}
.sample-page__first-section--second-line {
    font-size: 24px;
    background-color: forestgreen;
    color: pink;
    text-align: center;
    padding: 10px;
}
.sample-page__first-section--second-line-link {
    color: red;
    font-size: 28px;
    text-transform: uppercase;
}

用 @scope 重構(gòu)第一部分,我們現(xiàn)在就有了一個更簡潔的樣式定義:

.first-section {
    font-size: 24px;
    border: solid;
    padding: 40px;
    margin: 20px;
}
/* donut scope */
@scope (.sample-page) to (.second-section) {
    p {
        font-size: 24px;
        background-color: forestgreen;
        color: pink;
        text-align: center;
        padding: 10px;
    }
    a {
        color: red;
        font-size: 28px;
        text-transform: uppercase;
    }
}

這樣做的另一個好處是,HTML 視圖更小,更容易閱讀??紤]到之前。

<section className="sample-page__first-section">
    <p className="sample-page__first-section--first_line">
        some text
    </p>
    <p className="sample-page__first-section--second-line">
        some text and then a{' '}
        <a
            className="sample-page__first-section--second-line-link"
            href="/"
        >
            back link
        </a>
    </p>
</section>

然后。

<section className="first-section">
    <p>some text</p>
    <p>
        some text and then a <a href="/">back link</a>
    </p>
</section>

通過這兩個示例組件,我們可以對每個部分進行重構(gòu)。最終注意到它是如何使樣式更簡潔、更易讀的。

@scope 與 BEM 相比的其他優(yōu)勢

除了將 BEM 重構(gòu)為 @scope 的優(yōu)勢外,使用 @scope 還可以更好地控制 CSS 級聯(lián)。CSS 級聯(lián)是一種算法,它定義了網(wǎng)絡(luò)瀏覽器如何處理組成 HTML 頁面上元素的樣式條件。

在處理任何前端項目時,開發(fā)者可能需要處理由于樣式層疊而產(chǎn)生的奇怪結(jié)果。通過使用@scope,可以通過緊密限定元素范圍來控制層疊的副作用。

文件 no_scope.html 的樣式和一些元素定義如下:

<!DOCTYPE html>
<html>
    <head>
        <title>Plain HTML</title>
        <style>
            .light {
                background: #ccc;
            }
            .dark {
                background: #333;
            }
            .light a {
                color: red;
            }
            .dark a {
                color: yellow;
            }
            div {
                padding: 2rem;
            }
            div > div {
                margin: 0 0 0 2rem;
            }
            p {
                margin: 0 0 2rem 0;
            }
        </style>
    </head>
    <body>
        <div class="light">
            <p><a href="#">First Level</a></p>
            <div class="dark">
                <p><a href="#">Second Level</a></p>
                <div class="light">
                    <p><a href="#">Third Level</a></p>
                </div>
            </div>
        </div>
    </body>
</html>

結(jié)果如下:

這里的問題是,根據(jù)已定義的 CSS, Third Level 應(yīng)為紅色文本,而不是黃色。這是 CSS 級聯(lián)的副作用,因為頁面樣式是根據(jù)外觀順序來解釋的,因此 Third Level 被認(rèn)為是黃色而不是紅色。通過 Bram.us 原文中的圖表,我們可以看到 CSS 級聯(lián)評估選擇器和樣式的順序:

如果不使用 @scope ,CSS 級聯(lián)將直接從 "特定性 "轉(zhuǎn)為 "外觀順序"。使用 @scope 后,CSS 級聯(lián)將首先考慮 @scope 元素。您可以通過在示例中為 .light 和 .dark 樣式添加 @scope 來了解其效果。

首先,將原始 HTML 和 CSS 修改如下:

<!DOCTYPE html>
<html>
    <head>
        <title>Plain HTML</title>
        <style>
            .light {
                background: #ccc;
            }
            .dark {
                background: #333;
            }
            div {
                padding: 2rem;
            }
            div > div {
                margin: 0 0 0 2rem;
            }
            p {
                margin: 0 0 2rem 0;
            }
            @scope (.light) {
                :scope {
                    background: white;
                }
                a {
                    color: red;
                }
            }
            @scope (.dark) {
                :scope {
                    background: black;
                }
                a {
                    color: yellow;
                }
            }
        </style>
    </head>
    <body>
        <div class="light">
            <p><a href="#">First Level</a></p>
            <div class="dark">
                <p><a href="#">Second Level</a></p>
                <div class="light">
                    <p><a href="#">Third Level</a></p>
                </div>
            </div>
        </div>
    </body>
</html>

輸出結(jié)果如下:

總結(jié)

在本文中,我們探討了將 BEM 風(fēng)格應(yīng)用程序重構(gòu)為使用 Chrome 瀏覽器中新推出的 @scope 功能的方法。我們介紹了 @scope 的工作原理,然后將一個簡單的頁面從 BEM 重構(gòu)為 @scope 。

新的 @scope 功能有可能成為前端開發(fā)人員的一大優(yōu)勢。不過,其他瀏覽器也必須實現(xiàn)支持,這可能需要時間。在此之前,這絕對是一個有趣的功能,對前端項目的樣式設(shè)計可能會有很大幫助。

責(zé)任編輯:姜華 來源: 大遷世界
相關(guān)推薦

2021-01-06 08:48:35

CSS 命名模塊

2022-06-27 08:47:29

BEM修飾符元素

2022-05-27 08:25:55

容器Spring

2009-12-01 16:12:37

PHP HTML截取代

2013-11-28 09:24:57

SDN傳統(tǒng)網(wǎng)絡(luò)

2013-11-29 10:34:55

SDN網(wǎng)絡(luò)基礎(chǔ)設(shè)施

2021-07-14 14:06:06

CSS前端瀏覽器

2021-08-19 06:58:48

CSS頁面布局

2019-09-23 11:03:55

IPv6IPv4網(wǎng)絡(luò)

2016-11-02 09:38:05

容器虛擬機服務(wù)器

2010-04-20 15:31:48

英特爾安騰9300

2010-09-01 16:35:22

TDMOIPWLAN

2022-12-12 11:11:05

2021-11-15 09:44:49

Webpack 前端 Scope Hois

2010-05-12 10:19:14

英特爾安騰謎局

2009-05-26 08:51:38

HTML 5FlashOpera

2023-10-16 09:26:48

CSS類型轉(zhuǎn)換

2013-10-11 11:06:53

CSS前端

2022-05-12 09:01:41

CSSCompat定位

2013-11-20 09:26:21

AngularJSJavaScript
點贊
收藏

51CTO技術(shù)棧公眾號