1 คะแนน โดย GN⁺ 1 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ย้ายบางเว็บไซต์จาก Tailwind ไปใช้ semantic HTML และ vanilla CSS พร้อมเลือกนำเฉพาะกฎที่จำเป็นจาก Tailwind มาสร้างใหม่เอง
  • ยังคงระบบที่คุ้นเคยอย่าง preflight reset, ชุดสี และ font scale ของ Tailwind ไว้ แต่ย้ายมาอยู่ใน vanilla CSS ด้วย CSS variables และการแยกไฟล์
  • แบ่ง CSS ส่วนใหญ่ออกเป็น ไฟล์ตามคอมโพเนนต์ และใช้คลาสเฉพาะ เพื่อลดโอกาสที่การแก้คอมโพเนนต์หนึ่งจะไปทำอีกคอมโพเนนต์พังแบบไม่รู้ตัว
  • เหตุผลที่เริ่มออกจาก Tailwind ได้แก่ การพึ่งพา build system ของ Tailwind รุ่นใหม่, ไฟล์ tailwind.min.css ขนาด 2.8MB, การปะปนกับ vanilla CSS และข้อจำกัดของ CSS ในแบบ Tailwind
  • ในการออกแบบ responsive ผู้เขียนอยากใช้ CSS grid อย่าง auto-fit และ grid-template-areas มากกว่า breakpoint รวมถึงสนใจเรียนรู้ @layer, @scope และ container queries

ย้ายโครงสร้างที่เรียนรู้จาก Tailwind มาใช้กับ vanilla CSS

  • ตอนเริ่มใช้ Tailwind ครั้งแรกเมื่อ 8 ปีก่อน ผู้เขียนยังไม่รู้ว่าจะจัดโครงสร้างโค้ด CSS อย่างไร และ Tailwind ก็เป็นตัวเลือกที่ดีกว่าความ สับสนวุ่นวายเต็มรูปแบบ มาก
  • ช่วงประมาณสัปดาห์ที่ผ่านมา ผู้เขียนย้ายบางเว็บไซต์จาก Tailwind ไปเป็น semantic HTML + vanilla CSS และลงมือเลือกสร้างใหม่เองเฉพาะส่วนของกฎที่เคยได้จาก Tailwind และยังต้องการใช้อยู่
  • หลังอ่าน A whole cascade of layers และ How I write CSS in 2024 ก็ยิ่งชัดเจนว่า codebase CSS ทุกชุดต้องมีระบบสำหรับจัดการเรื่องที่เป็นคนละความสนใจ เช่น layout, ฟอนต์, สี และคอมโพเนนต์ที่ใช้ร่วมกัน
  • ใน Tailwind มีระบบอย่าง reset stylesheet, ชุดสี และ font scale อยู่แล้ว และส่วนที่คุ้นเคยกับใช้งานได้ดีก็สามารถเลียนแบบใน vanilla CSS ได้

ระบบหลักที่วางไว้ใน CSS codebase

  • reset

    • ใช้ preflight styles ของ Tailwind โดยคัดลอกมาจาก tailwind.css ช่วงแรกประมาณ 200 บรรทัด
    • ผู้เขียนคุ้นกับ Tailwind reset มานาน และกฎที่ใส่ box-sizing: border-box ให้ทุก element ก็ทำให้ความกว้างของ element รวม padding อยู่ด้วย
      * { box-sizing: border-box; }
    
    • อาจมีการพึ่งพากฎ reset อื่น ๆ แบบไม่รู้ตัว เช่น html {line-height: 1.5;} และถ้าจะเขียน CSS โดยไม่มีกฎพวกนี้ ก็ดูเหมือนต้องใช้เวลาปรับตัวมาก
  • components

    • CSS ส่วนใหญ่ถูกจัดเก็บเป็น ไฟล์ตามคอมโพเนนต์ คล้ายกับคอมโพเนนต์ใน Vue หรือ React
    • แต่ละคอมโพเนนต์มีคลาสเฉพาะของตัวเอง และจัดให้ CSS ของคอมโพเนนต์หนึ่งไม่ไปเขียนทับ CSS ของอีกคอมโพเนนต์
    • ในทางปฏิบัติ CSS ที่อยากแก้จริง ๆ ราว 80% อยู่ในไฟล์คอมโพเนนต์ ดังนั้นเวลาแก้คอมโพเนนต์ 100 บรรทัด ก็คิดแค่ 100 บรรทัดนั้นพอ
    • ตัวอย่างเช่น คอมโพเนนต์ .zine อาจมี HTML แบบนี้
      <figure class="zine horizontal">
          <img src="whatever.jpg">
      </figure>
    
    • ฝั่ง CSS จะใช้ nested selectors เพื่อรวมสถานะอย่าง .horizontal, .vertical และ :hover ไว้ภายในคอมโพเนนต์
      .zine {
        ...
        &.horizontal {
          ...
        }
        &.vertical {
          ...
        }
        &:hover {
          ...
        }
      }
    
    • แม้จะยังไม่ได้ใช้วิธีแบบ Web Components หรือ @scope เพื่อกันการรบกวนกันระหว่างคอมโพเนนต์ในเชิงโปรแกรม แต่แค่ตั้งธรรมเนียมและยึดตามนั้นก็ช่วยได้มากแล้ว
  • colours

    • ใน colours.css จะรวม CSS variables ที่หยิบมาใช้ได้เมื่อจำเป็น
    • สีเป็นเรื่องยาก และในการรีแฟกเตอร์ครั้งนี้ผู้เขียนไม่อยากกลับไปทบทวนการใช้สีใหม่ จึงยังคงแนวทางเดิมไว้
    • กฎเดียวคือให้ระบุสีทั้งหมดที่ใช้ในเว็บไซต์ไว้ในไฟล์นี้
      :root {
        --pink: #fea0c2;
        --pink-light: #F9B9B9;
        --red: #f91a55;
        --orange: rgb(222, 117, 31);
        ...
      }
    
  • font sizes

    • ใน Tailwind แค่เลือกขั้นขนาดอย่าง text-lg, xl, 2xl ก็พอ จึงไม่ต้องจำว่าจะใช้ em, px หรือ rem
    • เพื่อคงประสบการณ์แบบนั้นใน vanilla CSS ผู้เขียนจึงนิยามตัวแปรขนาดที่นำมาจาก Tailwind
      --size-xs: 0.75rem;
        --line-height-xs: 1rem;
    
        --size-sm: 0.875rem;
        --line-height-sm: 1.25rem;
    
    • ขนาดฟอนต์ถูกกำหนดผ่านตัวแปร ซึ่งแม้จะยืดยาวกว่า Tailwind เล็กน้อย แต่ตอนนี้ก็ยังเป็นวิธีที่น่าพอใจ
      h3 {
        font-size: var(--size-lg);
        line-weight: var(--line-weight-lg);
      }
    
  • utilities

    • องค์ประกอบที่ซ้ำข้ามหลายคอมโพเนนต์ เช่น ปุ่ม จะถูกจัดไว้ในหมวด utilities
    • utility classes บางตัว เช่น .sr-only สำหรับ element ที่ควรให้ผู้ใช้ screen reader เห็นเท่านั้น ถูกคัดลอกมาจาก Tailwind
    • ผู้เขียนพยายามคงส่วนนี้ให้เล็ก และระมัดระวังเวลาแก้ไข
  • base

    • สไตล์ “base” คือสไตล์ที่ใช้กับทั้งเว็บไซต์โดยตรง
    • เพราะยังไม่มั่นใจพอจะบังคับสไตล์จำนวนมากทั้งไซต์ จึงตั้งใจให้ส่วนนี้เล็กมาก
    • ตอนนี้มีกฎที่รู้สึกว่าโอเคอยู่ 2 อย่างสำหรับ <section> และ a โดยกฎของ <section> อาจเปลี่ยนในภายหลัง
      /* put a 950px column in the middle of each <section> */
      section {
        --inner-width: 950px;
        padding: 3rem max(1rem, (100% - var(--inner-width))/2);
      }
    
      a {
        color: var(--orange);
      }
    
    • สำหรับ base styles วิธีที่ดูง่ายที่สุดคือเริ่มจากเกือบว่างไว้ก่อน แล้วค่อยย้ายสิ่งที่พบว่าอยากใช้ร่วมกันจากคอมโพเนนต์ขึ้นมาไว้ใน base แบบ bottom-up
  • spacing

    • วิธีจัดการ padding และ margin ยังไม่ได้ถูกกำหนดลงตัวทั้งหมด
    • ตอนใช้ Tailwind ผู้เขียนมักใส่ padding กับ margin แบบเฉพาะหน้าไปเรื่อย ๆ จนกว่าจะได้หน้าตาที่ต้องการ และตอนนี้กำลังมองหาวิธีที่มีหลักการกว่านั้น
    • ตอนนี้พยายามให้คอมโพเนนต์ layout ชั้นนอกเป็นผู้รับผิดชอบเรื่องระยะห่างให้มากที่สุด
    • ถ้าอยากเว้นระยะเท่ากันระหว่างลูกใน <section> ที่มีลูกหลายตัว ก็อาจใช้กฎแบบนี้
      section > *+* {
        margin-top: 1rem;
      }
    
  • responsive design

    • ใน Tailwind ผู้เขียนใช้ ไวยากรณ์แบบ media query เยอะ เช่น md:text-xl ที่จะใช้สไตล์ text-xl เมื่อเกินขนาดที่กำหนด
    • ตอนนี้พยายามสร้าง layout ด้วย CSS grid ที่ยืดหยุ่นกว่าและไม่ต้องพึ่ง breakpoint มากนัก
    • การใช้ auto-fit ช่วยให้บนหน้าจอใหญ่เป็น 2 คอลัมน์ และบนหน้าจอเล็กเป็น 1 คอลัมน์โดยอัตโนมัติ
      display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), max-content));
        justify-content: center;
    
    • ยังใช้ grid-template-areas เยอะด้วย และมองว่านี่เป็นฟีเจอร์ยอดเยี่ยมที่ใช้กับ Tailwind ไม่ได้
    • แหล่งอ้างอิงที่ใช้คือบทความของ CSS Tricks A responsive grid layout with no media queries
  • build system

    • ระหว่างพัฒนาไม่จำเป็นต้องมี build system แยก
    • CSS มี @import ในตัวอยู่แล้ว จึงสามารถแยกไฟล์แล้วนำเข้ามาใช้ได้
      @import "reset.css";
      @import "typography.css";
      @import "colors.css";
    
    • CSS ยังมี nested selectors ในตัวด้วย
      .page {
        h2 { ...}
      }
    
    • ถ้าอยาก bundle ไฟล์ CSS สำหรับ production ก็สามารถใช้ esbuild ได้
      esbuild style.css --bundle --loader:.svg=dataurl  --loader:.woff2=file --outfile=/tmp/out.css
    
    • โดยทั่วไปผู้เขียนพยายามเลี่ยงการใช้ระบบ build สำหรับ CSS และ JS แต่สำหรับ esbuild มองว่าโอเค เพราะอิงเว็บมาตรฐานและเป็น static Go binary
    • ผู้เขียนเคยเขียน บทความเกี่ยวกับ esbuild และ Vue ไว้เมื่อปี 2021

เหตุผลที่ออกจาก Tailwind

  • ตั้งแต่ปี 2018 เป็นต้นมา Tailwind พึ่งพา build system มากขึ้นมาก และดูเหมือนว่า Tailwind รุ่นใหม่จะใช้งานโดยไม่มี build system ไม่ได้แล้ว ทำให้ผู้เขียนใช้ Tailwind v2 มาหลายปี
  • ดูเหมือนจะมีทางเลือกสำหรับใช้ Tailwind โดยไม่ต้องมี build system คือ litewind
  • แม้ Tailwind จะถูกออกแบบมาให้ใช้ร่วมกับ build system ตั้งแต่แรก แต่ในทางปฏิบัติผู้เขียนไม่ได้ทำแบบนั้น จึงมีไฟล์ tailwind.min.css ขนาด 2.8MB อยู่ในหลายโปรเจกต์ ซึ่งให้ความรู้สึกแปลกอยู่พอสมควร
  • ตอนนี้ผู้เขียนเก่ง CSS มากกว่าตอนเริ่มใช้ Tailwind ครั้งแรก
  • ท้ายที่สุด Tailwind ก็มีข้อจำกัด และเมื่ออยากทำอะไรใน CSS ที่แปลกหรือเฉพาะทาง ก็ไม่ได้ทำได้เสมอไป
  • ข้อจำกัดเหล่านั้นอาจมีประโยชน์มาก และจริง ๆ ตอนย้ายมา vanilla CSS ผู้เขียนก็สร้างข้อจำกัดบางอย่างของ Tailwind กลับขึ้นมาใหม่ แต่ตอนนี้อยากเลือกใช้เฉพาะข้อจำกัดที่จำเป็น
  • มีเว็บไซต์บางแห่งที่ภายในโปรเจกต์เดียวกันปะปนกันระหว่าง vanilla CSS กับ Tailwind และผู้เขียนพบว่าการดูแลรักษาแบบนั้นไม่สนุก
  • ผู้เขียนอยากรู้ว่าการเขียน semantic HTML มากขึ้นจะให้ความรู้สึกอย่างไร

ฟีเจอร์ CSS ที่อยากลองเรียนต่อไป

  • @layer เป็นฟีเจอร์สำหรับจัดการ cascade layer ซึ่งยังไม่ได้ใช้ แต่เป็นสิ่งที่อยากเรียนรู้
  • @scope เป็นฟีเจอร์ที่น่าสนใจสำหรับจัดการสไตล์ในคอมโพเนนต์หรือขอบเขตเฉพาะ
  • container queries เป็นฟีเจอร์สำหรับการออกแบบ responsive โดยอิงจากคอนเทนเนอร์ ซึ่งผู้เขียนอยากศึกษา
  • subgrid เป็นอีกฟีเจอร์ด้าน CSS grid ที่อยู่ในรายการสิ่งที่สนใจ

บทสรุปที่ไม่ได้ปฏิเสธ Tailwind ไปทั้งหมด

  • ตอนนี้แม้จะกำลังค่อย ๆ ออกจาก Tailwind แต่ผู้เขียนก็ยังพอใจกับการเริ่มใช้ Tailwind ในตอนนั้น
  • ผู้เขียนได้เรียนรู้อะไรมากมายจากการใช้ Tailwind และแม้จะลบ tailwind.min.css ออกไปแล้ว ก็ยังใช้บางส่วนของ Tailwind ภายในเว็บไซต์ต่อได้
  • ส่วนที่ทำให้ CSS ของ wizardzines.com ดูเท่และสนุกนั้น มาจาก Melody Starling ผู้ที่ออกแบบและเขียน CSS เดิมของเว็บไซต์
  • ระหว่างทำงานด้าน CSS ผู้เขียนอ่านบทความจำนวนมากจาก CSS Tricks, Smashing Magazine และที่อื่น ๆ และพบว่าชุมชน CSS แบ่งปันวิธีปฏิบัติในการทำงานกันเยอะมาก ซึ่งช่วยได้มาก

1 ความคิดเห็น

 
GN⁺ 1 시간 전
ความเห็นจาก Lobste.rs
  • สำหรับโปรเจกต์ส่วนตัว เดี๋ยวนี้แทบไม่ใช้ เฟรมเวิร์ก CSS/JavaScript แล้ว
    เพราะถ้าไม่มี dependency ก็จะไม่มีช่องโหว่ในซัพพลายเชนเกิดขึ้นได้ แน่นอนว่าช่องโหว่ไม่ได้มีแค่นั้น แต่ก็ช่วยได้

    • ฉันเองก็กลับไปใช้ HTML/CSS/JS แบบเพียวๆ พอสมควรเหมือนกัน แล้วค่อยเสริมเฉพาะสิ่งที่ทำเองเล็กน้อย
      เป็นผลรวมของความล้าจากเฟรมเวิร์ก, ภาระจาก npm audit และการที่มี LLM ทำให้ไม่ต้องสนใจคำตัดสินของคนอื่นเรื่องวิธี implement มากเท่าเดิม เช่นคำถามประมาณว่า “ทำไมไม่ใช้ React กับ Tailwind”
  • นี่ก็เป็นแค่ วิธีการทำงานของ CSS เอง
    เวลาเห็นคนไม่รู้เรื่องนี้แล้วใช้ Tailwind แบบไม่ลืมหูลืมตา ก็อยากออกไปตะโกนใส่ก้อนเมฆเลย สำหรับฉัน Tailwind 90% ก็คือ inline style ที่เปลี่ยนแค่ไวยากรณ์ และอาจมองได้ว่าแค่ดีกว่าแท็ก <FONT> ขึ้นมาขั้นหนึ่ง

    • ไม่แน่ใจว่าคอมเมนต์นี้ต้องการสื่ออะไร แต่ตลอดเวลาที่ใช้ Tailwind มาเกือบ 8 ปี ฉันเห็นคอมเมนต์แนวดูถูกผู้ใช้ Tailwind แบบนี้มานับครั้งไม่ถ้วน และไม่มีอันไหนเลยที่ช่วยให้เลิกใช้ Tailwind หรือพัฒนาฝีมือ CSS ได้
      บล็อกโพสต์นี้อธิบายในสิ่งที่ฉันจำเป็นต้องรู้จริงๆ
    • คำพูดที่ว่า “Tailwind 90% คือ inline style ที่เปลี่ยนแค่ไวยากรณ์” นั้นไม่ค่อยตรงนัก
      Tailwind ทำงานต่างจาก inline style มาก และจริงๆ แล้วคล้าย CSS มากกว่ามาก อย่างที่บทความชี้ไว้ นิสัยที่ดีหลายอย่างซึ่งทำให้ใช้ Tailwind ได้เก่ง ก็เป็นนิสัยเดียวกับที่จำเป็นต่อการเขียน CSS อย่างมีประสิทธิภาพ Tailwind ใกล้เคียงกับการแนบ บล็อก CSS ที่มีสโคปโดยนัย ให้ทุกองค์ประกอบ โดยใช้ DSL ที่มีลักษณะเฉพาะมากกว่า
    • การรู้ว่า CSS ทำงานอย่างไร กับการรู้ว่า จะใช้อย่างมีประสิทธิภาพได้อย่างไร เป็นคนละเรื่องกันมาก
      ฉันเข้าใจการทำงานของ CSS ดี แต่ CSS แบบเพียวๆ ยังรู้สึกหนักมือ และฉันก็ไม่ค่อยเก่งด้านกราฟิกดีไซน์ เลยยังใช้ Tailwind อยู่ บทความนี้ให้ไอเดียในการจัดโครงสร้าง CSS โดยอิงจาก Tailwind
  • สำหรับคนที่ตามกระแสล่าสุดไม่ค่อยทัน บทความนี้ดูเหมือนจะแสดงให้เห็น แนวปฏิบัติ CSS สมัยใหม่ ได้ค่อนข้างดี
    ชอบตรงที่มีลิงก์ต่อไปยังบทความที่เป็นแรงบันดาลใจหลายชิ้นด้วย เหมาะจะเก็บไว้อ่าน ตอนนี้ฉันเพิ่งอ่านแค่ "no outer margin"
    แต่ก็ยังแอบสงสัยเล็กน้อยกับแนวทางตั้ง default style แบบ “จากล่างขึ้นบน” ไม่รู้ว่าควรทำอย่างอื่นแทนไหม และมันก็ดูน่าลองอยู่ แต่ default style โดยธรรมชาติก็เป็นเรื่องที่จัดการยากอยู่แล้ว

  • บทความนี้ดีมากจริงๆ
    ฉันเองก็ค่อยๆ เรียน CSS ไปพร้อมกับทำเว็บเล็กๆ หลายแบบ และคิดว่าถ้าเริ่มต้นมาพร้อม วิธีคิดเชิงระบบ แบบนี้ก็น่าจะช่วยได้มาก แม้จะค่อนข้างไม่ชอบเฟรมเวิร์ก แต่พอไม่ได้ใช้ ก็ถึงจะทำสิ่งที่ต้องการได้ก็จริง ทว่ามักรู้สึกเหมือนลอยอยู่กลางอากาศแบบไร้โครงสร้าง

  • ชอบตรงที่ไม่ได้พูดว่า “Tailwind ไม่ดี ก็ไปใช้ CSS เถอะ” แต่เป็นแนวว่า “Tailwind ยอดเยี่ยม แต่ตอนนี้อาจไม่จำเป็นแล้วก็ได้
    ฉันมีปัญหากับการจัดโครงสร้าง CSS ด้วยมือตลอด และบทความนี้ทำให้เริ่มคิดมันในมุมที่ต่างออกไปมาก

  • ตอนจัดระเบียบ CSS ฉันพบว่า เทคนิคการจัดโครงสร้าง นี้มีประโยชน์มาก: https://rstacruz.github.io/rscss/
    โดยรวมแล้วมันเข้ากันได้ดีกับสิ่งที่ jvns อธิบายในบทความต้นทาง และช่วยเติมเรื่องโครงสร้างกับความเป็นระเบียบเข้าไปอีกหน่อย