CSS @layer เพิ่มระดับชั้นความสำคัญให้กับ CSS

เมื่อต้องเจอการแก้ไข CSS หลายคนอาจจะเคยพบเจอ !important ทุกที่มาแล้ว เพราะไม่รู้จะแก้ปัญหายังไง เขียน CSS เพิ่มเข้าไปแล้วหน้าตามันก็ไม่เปลี่ยนสักที การเขียน CSS แบบเก่ามันอ้างอิงจากการไล่อ่าน Selector ที่ถูกโหลดเข้ามาต่อกันเรื่อยๆ แล้วปัญหามันจะเริ่มเกิดเมื่อไฟล์ CSS มันยาวมากเกินไปจนหาที่แก้ไม่ถูก สุดท้ายก็จิ้มเอาตรง Inspect ที่บราวเวอร์แล้วก็ซัด !important ลงไปเลย

หากใครกำลังจะรื้อระบบวางโครงสร้าง CSS ใหม่ หรือกำลังทำ Design System อยู่ก็อยากจะแนะนำให้เอา @layer ของ CSS มาใช้ เพื่อความเป็นระเบียบเรียบร้อยเพิ่มยิ่งขึ้นของการเขียน

สมมุติว่าเราตกลงกันในทีมจะวางโครงสร้างไฟล์ CSS แบบนี้

  • Setting ใช้สำหรับพวกจัดการค่า default ของ css ที่ต่างกันในแต่ละ User Agent
  • Framework ถ้าเราเริ่มสร้าง framework ต่างๆ เอาเข้ามาใส่ตรงนี้ พวกการจัดการ layout การแสดงผลโครงสร้างใหญ่ๆ
  • Design System เอาไว้สำหรับการสั่งงานระบบ Atomic UI ที่กำหนดใน design system ของเราหรืออื่นๆ
  • Theme ใช้สำหรับ Override และเพิ่มเติม utilities อื่นๆ หรือเราแก้ธีมใหม่ให้ลูกค้าโดยใช้โครงสร้างพื้นฐานจากชุด Framework และ Design System เดิม

เราเอามาเขียนเป็น Layer แบบนี้

@layer settings, framework, design-system, theme;

โครงสร้างจะถูกอ่านแบบ override กันไปเรื่อยๆ โดยที่ theme จะสำคัญที่สุด

ตัวอย่าง หากเราจะเขียนโครงสร้างแยกแล้วนำแต่ละส่วนมาใช้งาน ขอยกตัวอย่าง button สักอัน

<button>Primary Button</button>

โครงสร้าง CSS ที่เขียนได้ประมาณนี้

@layer settings, framework,  design-system, theme;

        @layer settings {
          *,
          *::before,
          *::after {
            box-sizing: border-box;
          }
          * {
            margin: 0;
          }
          body {
            line-height: 1.5;
            -webkit-font-smoothing: antialiased;
          }
          img,
          picture,
          video,
          canvas,
          svg {
            display: block;
            max-width: 100%;
          }
          input,
          button,
          textarea,
          select {
            font: inherit;
          }
          p,
          h1,
          h2,
          h3,
          h4,
          h5,
          h6 {
            overflow-wrap: break-word;
          }
          button {
            border: none;
          }
        }

        @layer framework {
          :root {
            --primary-btn-txt: hsla(0 0% 20% / 1);
            --primary-btn-bg: hsla(0 0% 80% / 1);
            --btn-rsdius: 0.5em;
            --btn-space: 0.5em 1em;
          }
          body {
            font-family: "Roboto", sans-serif;
          }
          button {
            padding: var(--btn-space);
            border-radius: var(--btn-rsdius);
          }
        }

        @layer design-system {
          :root {
            --primary-btn-txt: hsla(50 82% 57% / 1);
            --primary-btn-bg: hsla(247 86% 55% / 1);
            --btn-rsdius: 0.75em;
            --btn-space: 0.5em 1.2em;
          }
          button {
            color: var(--primary-btn-txt);
            background-color: var(--primary-btn-bg);
            border-radius: var(--btn-rsdius);
          }
        }

        @layer theme {
          :root {
            --primary-btn-txt: hsla(0 0% 100% / 1);
            --primary-btn-bg: hsla(265 82% 57%/ 1);
            --btn-rsdius: 40em;
          }

          button {
            color: var(--primary-btn-txt);
            background-color: var(--primary-btn-bg);
            border-radius: var(--btn-rsdius);
            text-transform: uppercase;
          }
        }

ตรงที่เป็น Layer settings นั้นเอาไว้สั่งงาน reset ค่าต่างๆ ให้แต่ละ user agent เข้าใจตรงกัน การแสดงผลจริงๆ จะเริ่มตั้งแต่ framwork ไปยัง design-system แล้วไปยัง theme

หากเราจะเรียกใช้ไฟล์ style.css ในงานแล้วเรามี css ไฟล์อื่นๆ แยกอยู่เราก็สามรถดึงเข้ามารวมกันแล้วสั่งให้มันทำ layer 

เราใช้  @import ไฟล์เข้ามาสั่ง @layer ให้มันตามโครงสร้างที่วางเอาไว้ ก็สามารถสั่งต่อท้ายไฟล์ที่ import เข้ามาได้เลย เช่น

     @import reset.css layer(settings);
     @import main-layout.css layer(framework);
     @import design.css layer(design-system);
     @import typo.css layer(design-system);
     @import client.css layer(theme);

แล้วในฟล์ style.css หากเราเขียน CSS ลงไปโดยไม่ @layer ให้มัน มันจะ override ทุกอย่างที่กล่าวมา แล้วเราก็จะจัดหนักกับ !important ให้มันเหมือนเดิม ผ่าง!

มีความสุขกับการใช้ชีวิตครับ

อ่านเพิ่มเติม
CSS Cascading and Inheritance Level 5

Back to Top

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back to Top