3 คะแนน โดย GN⁺ 2024-03-22 | 3 ความคิดเห็น | แชร์ทาง WhatsApp
  • Dropflow เป็นเอนจินเลย์เอาต์ CSS ที่สร้างขึ้นเพื่อสำรวจ มาตรฐาน CSS พื้นฐาน ได้แก่ inline, block, float, positioning และในอนาคตคือ table โดยไม่ได้มุ่งเป้าไปที่ flexbox และ grid
  • สามารถใช้กับ Node และ node-canvas เพื่อ สร้าง PDF/รูปภาพ บนแบ็กเอนด์ และในเบราว์เซอร์สามารถเรนเดอร์ rich text ที่มีการตัดบรรทัดลงบน canvas ได้
  • เลย์เอาต์ข้อความรองรับ ข้อความสองทิศทางและ RTL, การ fallback ฟอนต์ระดับกราฟีม, เครื่องหมายกำกับเสียงแบบมีสี, การลงทะเบียนฟอนต์ OpenType/TrueType และ shaping ที่อิง HarfBuzz
  • ขอบเขตการรองรับ CSS มีมากกว่า 30 พร็อพเพอร์ตี โดย float, clear, display: inline-block, position: relative, overflow, z-index, zoom เป็นต้นใช้งานได้ และ table, absolute, fixed, transform เป็นต้นยังอยู่ในขั้นวางแผน
  • ประสิทธิภาพสูงสุดได้จาก hyperscript API ที่ข้ามการ parse HTML/CSS และ object style ที่นำกลับมาใช้ซ้ำได้ โดยบน MacBook Pro ปี 2019 สามารถแปลง The Little Prince ที่มีมากกว่า 500 ย่อหน้าจาก HTML เป็นรูปภาพได้ในเวลาต่ำกว่า 160ms

ขอบเขตเลย์เอาต์ CSS ที่ Dropflow ครอบคลุม

  • Dropflow เป็น เอนจินเลย์เอาต์ CSS ที่สร้างขึ้นเพื่อสำรวจขอบเขตของ foundational CSS standards
    • เป้าหมายคือ inline, block, float, positioning และในอนาคตคือ tables
    • flexbox และ grid ไม่ใช่เป้าหมาย
  • มีการใช้งาน เลย์เอาต์ข้อความ คุณภาพสูง และสามารถแสดงภาษาต่าง ๆ ทั่วโลกได้
  • มีการนำเสนอการใช้งานสองแบบ
    • ใช้ Node และ node-canvas เพื่อสร้าง PDF หรือรูปภาพบนแบ็กเอนด์
    • เรนเดอร์ rich text ที่ตัดบรรทัดได้ลงบน canvas ในเบราว์เซอร์

ฟีเจอร์หลัก

  • รองรับพร็อพเพอร์ตี CSS มากกว่า 30 รายการ รวมถึงพร็อพเพอร์ตีที่ซับซ้อนอย่าง float
  • ฟีเจอร์เกี่ยวกับข้อความครอบคลุมกว้าง
    • ข้อความสองทิศทาง และข้อความ RTL
    • ฟอนต์ fallback ระดับกราฟีม
    • เครื่องหมายกำกับเสียงแบบมีสี
    • การจัดการตัดบรรทัดที่เหมาะสม เช่น นำ padding เริ่มต้นไปไว้บรรทัดถัดไป
    • shaping ที่ปรับแต่งประสิทธิภาพแล้ว
  • นอกจาก HTML/CSS แล้ว ยังรองรับ hyperscript h() API ที่ส่ง style เป็น object ได้ด้วย
  • สามารถลงทะเบียนบัฟเฟอร์ OpenType/TrueType ได้ และจำเป็นต้องลงทะเบียน
  • <img> รองรับ JPEG, BMP, PNG, GIF แต่การรองรับอาจแตกต่างกันตามแบ็กเอนด์
  • style ที่สืบทอดและผ่าน cascade แล้วจะไม่ถูกคำนวณซ้ำสองครั้ง
  • มี type ครบถ้วน มีการทดสอบจำนวนมาก และตั้งเป้าให้ทำงานเร็ว

สถานะการรองรับ CSS

  • รายการที่ทำงานได้ใน Inline formatting ได้แก่ color, direction, font-family, font-size, font-stretch, font-style, font-weight, line-height, text-align, vertical-align, white-space, word-break, overflow-wrap, word-wrap, word-spacing เป็นต้น
  • ใน Inline formatting, font-variant, letter-spacing, tab-size, text-decoration, unicode-bidi อยู่ในสถานะ วางแผนไว้
  • ใน Block formatting, clear และ float ทำงานได้
    • horizontal-tb, vertical-lr, vertical-rl ของ writing-mode อยู่ในสถานะใช้งานได้บางส่วน
    • ใช้งานใน BFC แล้ว แต่ยังไม่ได้ใช้งานใน IFC
  • ใน Boxes and positioning มีพร็อพเพอร์ตีกล่องและการจัดวางหลายรายการที่ทำงานได้
    • background-clip, background-color, border-color, border-style, border-width
    • top, right, bottom, left
    • box-sizing
    • display: block, inline, inline-block, flow-root, none
    • height, margin, padding, overflow, width, z-index, zoom
    • position: relative
  • ใน Boxes and positioning, display: table, min/max-height, min/max-width, position: absolute, position: fixed, transform อยู่ในสถานะ วางแผนไว้

ลำดับการใช้งานพื้นฐาน

  • Dropflow ทำงานบนพื้นฐาน DOM ที่มี style ที่สืบทอดและคำนวณแล้ว เช่นเดียวกับเบราว์เซอร์
  • ลำดับทั่วไปมีดังนี้
    • ลงทะเบียนฟอนต์ด้วย FontFace ก่อนทำเลย์เอาต์
    • สร้าง object style ด้วย flow.style()
    • สร้าง DOM ด้วย flow.h()
    • เตรียม tree สำหรับเรนเดอร์ด้วย flow.dom()
    • ทำเลย์เอาต์และ paint ทั้ง canvas ด้วย renderToCanvas()
  • มี HTML API ให้ด้วย แต่แนะนำเฉพาะเมื่อประสิทธิภาพไม่สำคัญหรือเพื่อการเรียนรู้
    • การ parse ทำให้ใช้เวลาเพิ่ม และเพิ่มขนาด bundle อย่างมาก
    • ระบุไว้ว่าการ parse HTML นั้นเร็วได้เพราะ @fb55
    • ปัจจุบันรองรับเฉพาะแอตทริบิวต์ HTML style ส่วน class ยังไม่ทำงาน

ลักษณะด้านประสิทธิภาพ

  • ประสิทธิภาพเป็นเป้าหมายสูงสุด และสำคัญรองจากความถูกต้อง
  • มีตัวเลขประสิทธิภาพจากตัวอย่างดังนี้
    • แปลง 8 ย่อหน้าที่มี inline span หลายรายการและฟอนต์ต่างกันจาก HTML เป็นรูปภาพ ใช้เวลา 9ms บน MacBook Pro ปี 2019 และ 13ms บน MacBook Pro ปี 2012
    • แปลง The Little Prince ที่มีมากกว่า 500 ย่อหน้าจาก HTML เป็นรูปภาพ ใช้เวลา ต่ำกว่า 160ms บน MacBook Pro ปี 2019 และ ต่ำกว่า 250ms บน MacBook Pro ปี 2012
    • สร้างคำยาว 10 ตัวอักษรและทำเฉพาะเลย์เอาต์ ใช้เวลา ต่ำกว่า 25µs บน MacBook Pro ปี 2019 และ ต่ำกว่า 50µs บน MacBook Pro ปี 2012
  • ประสิทธิภาพที่เร็วที่สุดได้เมื่อสร้าง DOM โดยตรงด้วย hyperscript API และข้ามขั้นตอน parse HTML/CSS ทั่วไป
  • หากนำ object style กลับมาใช้ซ้ำจะได้ประโยชน์มากขึ้น
  • การ reflow ที่ความกว้างอื่นเร็วกว่าการสร้าง layout tree ใหม่

โครงสร้าง API

  • ขั้นพื้นฐานมีสองอย่าง
    • ลงทะเบียนฟอนต์
    • สร้าง DOM ด้วย Hyperscript API หรือ Parse API
  • ในการใช้งานแบบง่าย สามารถเรนเดอร์ DOM ลง canvas ได้โดยตรง
    • renderToCanvas(el, canvas) ใช้ width และ height ของ canvas เป็นขนาด viewport แล้วเรนเดอร์เลย์เอาต์ทั้งหมด
  • หากใช้ API ระดับล่างกว่า จะสามารถเก็บเลย์เอาต์ไว้ได้
    • โหลด resource ที่พึ่งพา
    • สร้าง layout ของ DOM
    • reflow layout
    • paint ไปยังเป้าหมาย เช่น HTML5 canvas
  • วิธีนี้ใช้สำหรับ reflow เป็นขนาดอื่น, ไม่ paint เลย์เอาต์ที่มองไม่เห็น หรือรับค่า intrinsics ได้

การจัดการฟอนต์

  • ขั้นแรกของโปรแกรม Dropflow คือการลงทะเบียนฟอนต์ที่จะถูกเลือกด้วยพร็อพเพอร์ตี CSS font
  • เนื่องจาก Dropflow ไม่ค้นหาฟอนต์ระบบ จึงต้องสร้างและเพิ่ม FontFace อย่างน้อยหนึ่งครั้ง
  • API ลงทะเบียนฟอนต์ใช้งาน subset ของ CSS Font Loading API และเพิ่มเมธอดนอกมาตรฐาน loadSync
  • ฝั่งเซิร์ฟเวอร์สามารถโหลด URL file:/// แบบ synchronous ด้วย readFileSync ได้
  • ArrayBuffer จะถูกโหลดทันทีใน constructor เช่นเดียวกับในเบราว์เซอร์
  • registerNotoFonts ลงทะเบียน font family Noto Sans ทั้งหมด
    • ฟอนต์จัดจำหน่ายโดย FontSource และโฮสต์โดย jsDelivr
    • เป็น import ขนาดใหญ่ เพราะมีฟอนต์ Noto Sans มากกว่า 200 รายการ และสตริง unicodeRange ของฟอนต์ CJK มีขนาดใหญ่
    • ระบุไว้ว่าสำหรับการใช้งาน production ในเบราว์เซอร์ การลงทะเบียนฟอนต์แยกเป็นรายตัวจะดีกว่า
    • สำหรับ Latin มีการลงทะเบียนฟอนต์ italic และสำหรับทุกสคริปต์มีการลงทะเบียน normal 400 และ bold 700
  • ภาษาจีน เกาหลี และญี่ปุ่นแชร์ Unicode code point ร่วมกัน แต่ตัวอักษรอาจเรนเดอร์ต่างกัน ดังนั้นหากเป็นไปได้ควรใช้ฟอนต์เฉพาะภาษานั้น ๆ

เลย์เอาต์, reflow, paint

  • layout(el) สร้าง layout ที่มี box tree, fragmentation tree และ glyph
    • box tree โดยรวมสอดคล้องกับ DOM tree แต่เพราะมีเนื้อหาข้อความแบบ anonymous จึงอาจมีกล่องมากขึ้น หรืออาจน้อยลงเพราะ display: none
  • reflow(layout, width = 640, height = 480) จัดวางกล่อง แบ่งข้อความเป็นบรรทัด และทำให้พร้อม paint
    • margin collapsing ของ block box
    • ส่งข้อความให้ HarfBuzz
    • ทำ font fallback ซ้ำ
    • reshaping ตามการตัดบรรทัดและ break point
    • จัดวาง float และจัดการ clear
    • จัดวาง shaped text span และ background ตาม direction และทิศทางข้อความ
    • คำนวณ intrinsics ของเนื้อหา float, inline-block, absolute
    • จัดการ position หลัง normal flow
  • เป้าหมายสำหรับ paint ปัจจุบันรองรับ Canvas และ SVG
    • paintToCanvas paint ไปยัง browser canvas, node-canvas หรือ context อื่นที่สอดคล้องกับมาตรฐานใกล้เคียงกัน
    • paintToSvg สร้างสตริง SVG และรวมกฎ @font-face ที่อ้างอิง URL ที่ส่งให้ FontFace
    • paintToSvgElements ไม่เพิ่ม <svg> และกฎ @font-face เพื่อใช้เมื่อวาดใน SVG ที่มีอยู่แล้ว
    • paintToHtml สร้าง flat list ขององค์ประกอบที่จัดตำแหน่งแบบ absolute แม้ไม่แนะนำให้ใช้ แต่อาจมีประโยชน์ระหว่างพัฒนา

DOM API และ environment hooks

  • HTMLElement รากที่ได้จาก Hyperscript และ Parse API มีเมธอดค้นหาองค์ประกอบด้วย tag name, id, class คล้ายกลุ่ม querySelector ของ browser
    • query(selector) คืนค่า HTMLElement หนึ่งตัวหรือ null
    • queryAll(selector) คืนค่า HTMLElement[]
  • HTMLElement อาจมีกล่อง render ที่เชื่อมอยู่
    • โดยทั่วไปมีหนึ่งกล่อง แต่ถ้ามี inline และ block content ปนกันอาจมีหลายกล่อง
    • BlockContainer ถูกสร้างสำหรับ absolute positioned element, floated element, inline-block, block-level element
    • ReplacedBox ถูกสร้างสำหรับรูปภาพ
  • Dropflow ออกแบบมาให้ปรับเข้ากับสภาพแวดล้อมหลากหลายได้
    • ในเบราว์เซอร์ โหลดฟอนต์และรูปภาพด้วย fetch และลงทะเบียนบัฟเฟอร์ฟอนต์กับ document.fonts
    • ใน Nodejs สามารถโหลดฟอนต์แบบ synchronous ด้วย fs.readFileSync
    • หากมี canvas backend และ node-canvas จะเรียก registerFont ของ node-canvas
    • node-canvas ไม่รองรับ font buffer จึงต้องใช้ URL file://
  • หากต้องการใช้ @napi-rs/canvas หรือ skia-canvas ต้องมีโค้ดไม่กี่บรรทัดเพื่อเชื่อม flow.environment.registerFont เข้ากับ API ลงทะเบียนฟอนต์นั้น
  • environment มี hook 6 รายการ
    • wasmLocator
    • registerFont
    • resolveUrl
    • resolveUrlSync
    • createDecodedImage
    • destroyDecodedImage

Text shaping ที่อิง HarfBuzz

  • Glyph layout ดำเนินการโดย HarfBuzz ที่คอมไพล์เป็น WebAssembly
  • ตั้งเป้าเรื่อง ความถูกต้อง ซึ่งเป็นสิ่งที่ทำได้ยากด้วยวิธีจับตำแหน่ง text span ผ่าน API measureText
  • ตัวอย่างเช่น หากใน Google Sheets ระบายสีเฉพาะ "V" ใน "AV" เป็นสีอื่น kerning จะหายไป ทำให้ตัวอักษรอยู่ห่างกันกว่าปกติ
    • เพราะมีการเรียก measureText และ fillText สองครั้งแยกตามตัวอักษร ทำให้ contextual glyph advance หายไป
  • Dropflow ใช้ HarfBuzz ที่ shaping boundary ที่หยาบกว่า ไม่ใช่ตรงจุดที่สีเปลี่ยน เพื่อรองรับฟอนต์ได้ถูกต้องยิ่งขึ้น
  • HarfBuzz ที่คอมไพล์เป็น WebAssembly สามารถให้ตัวชี้วัดประสิทธิภาพใกล้เคียงกับ measureText ของ CanvasRenderingContext2D
    • ระบุไว้ว่าแม้ไม่เร็วเท่า measureText แต่ก็ไม่ได้ช้ากว่ามาก
    • ระบุว่าทั้งสองอย่างไม่ใช่คอขวดหลักของสแตกเลย์เอาต์ข้อความ
  • เลย์เอาต์ข้อความที่อิง measureText ต้องมี word cache จึงจะทำงานเร็ว และระบุว่าแอป GSuite ใช้วิธีนี้
    • word cache ไม่สามารถรองรับฟอนต์ที่มีเอฟเฟกต์ข้ามช่องว่างได้
    • หากจะรองรับฟอนต์ดังกล่าว ต้อง binary search ที่ break index ของย่อหน้า ซึ่งระบุว่าช้ากว่าการส่งทั้งย่อหน้าให้ HarfBuzz มาก
    • เครื่องหมายกำกับเสียงแบบมีสีทำด้วย measureText ไม่ได้

โปรเจกต์ที่พึ่งพา

  • Dropflow ไม่มี dependency ใน package.json แต่ใช้ผลงานจากหลายโปรเจกต์
  • dependency ฝั่ง JavaScript ถูกเช็กอินไว้ในโปรเจกต์ และถูกแก้ไขในระดับต่าง ๆ เพื่อคงโฟกัสและหลีกเลี่ยงปัญหา dependency-of-dependency
  • โปรเจกต์หลักมีดังนี้

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

 
winterjung 2024-03-23

ชื่อเดิมคือ "Show HN: Dropflow, a CSS layout engine for node or <canvas>" นั่นเอง ตอนนี้กลายเป็น "GN⁺: HN แนะนำ: เอนจินเลย์เอาต์ CSS สำหรับ Node หรือ <canvas>, Dropflow</canvas>" ไปแล้วครับ

 
dlehals2 2024-03-22

มีแท็กอยู่ในชื่อเรื่อง เลยทำให้ส่วนชื่อบนหน้ารายละเอียดเพี้ยนไปสินะ.. ฮ่าๆ ควร escape หน่อย..

 
GN⁺ 2024-03-22
ความคิดเห็นบน Hacker News
  • ทุกวันนี้วิธีมาตรฐานในการสร้าง PDF สวย ๆ บนแบ็กเอนด์คือการเปิด เฮดเลสเบราว์เซอร์ แล้วใช้ Browser API แปลง HTML/CSS เป็น PDF แต่ต้นทุนในการรันอินสแตนซ์ของเบราว์เซอร์บนเซิร์ฟเวอร์และสเกลให้รองรับงานปริมาณมากนั้นค่อนข้างสูง
    เครื่องมือนี้เป็นตัวเปลี่ยนเกม เพราะตอนนี้สามารถออกแบบและสร้าง PDF ด้วย HTML/CSS ได้โดยไม่ต้องมีโอเวอร์เฮดของเบราว์เซอร์

    • น่าทึ่งที่เว็บมาไกลถึงจุดนี้ วิธีที่ดีที่สุดในการสร้างเอกสาร PDF สวย ๆ กลับเป็นการ รันเว็บเบราว์เซอร์ทั้งตัว บนเซิร์ฟเวอร์ คงเป็นเรื่องที่จินตนาการได้ยากในยุค 90 หรือ 2000
    • ข้อดีของการใช้เบราว์เซอร์คือ PDF ที่สร้างออกมาจะใช้ เวกเตอร์และฟอนต์ ส่วนแบบที่อิง Canvas น่าจะกลายเป็นภาพเป็นส่วนใหญ่ใน PDF ซึ่งสำหรับการใช้งานส่วนมากอาจไม่ใช่ปัญหาใหญ่
    • เคยใช้ https://ekoopmans.github.io/html2pdf.js/ และมันทำงานได้ค่อนข้างดี
    • สับสนนิดหน่อย ผมใช้ไลบรารี Prawn สำหรับสร้าง PDF ในแบ็กเอนด์ของโปรเจกต์ย่อยของตัวเองมานานพอสมควรแล้ว: https://github.com/prawnpdf/prawn
      เพียงแต่ PDF ที่ผมสร้างนั้นแน่นอนว่าไม่ได้สวยงามเท่าไร นั่นอาจเป็นความแตกต่างก็ได้
    • เคยทำ PDF renderer ให้ลูกค้าหลายราย และข้อกำหนดที่ใหญ่ที่สุดสำหรับ PDF คือ การเข้าถึงได้
      ทุกคนต้องเป็นไปตาม ADA จึงเปลี่ยนไปใช้ Canvas renderer ได้ยาก เพราะแบบนั้นการเข้าถึงได้จะหายไป
  • ดูดีมากจริง ๆ ที่งานก่อนหน้านี้ผมพัฒนาแพลตฟอร์มการเรียนรู้ออนไลน์แบบ immersive โดยใช้ Oculus Quest 2 ฝึกภาษาต่างประเทศให้บุคลากรกระทรวงกลาโหม และใช้ WebXR, Three.js เป็นต้น
    Unity3D ครั้งเดียวก็เกินพอแล้ว และผมก็ไม่อยากผ่านการตรวจของแอปสโตร์ด้วย เรามีกลุ่มอุปกรณ์ของตัวเองเลยไม่มีปัญหา
    หนึ่งในความท้าทายใหญ่ที่สุดคือการสร้างเวิร์กโฟลว์สำหรับคอนเทนต์บทเรียน และแทบต้องทำคนเดียวทั้งหมด อาจารย์ภาษาตัวจริงจะสร้าง PDF ด้วย PowerPoint แล้วอัปโหลด PDF เข้า content database ผ่านเอดิเตอร์เฉพาะที่ผมทำขึ้น เพื่อเอาไปวางในสภาพแวดล้อมการฝึก จากนั้นใช้ PDFJS เรนเดอร์ลงองค์ประกอบ Canvas แล้วใช้เป็นเท็กซ์เจอร์ของสี่เหลี่ยม 3D
    ถ้ามีเครื่องมือแบบนี้ ผู้คนก็คงไม่ต้องอ้อมไปทำสื่อด้วย PowerPoint วิธี PowerPoint ช่วยให้เวิร์กโฟลว์เร็วขึ้นมากเมื่อเทียบกับความพยายามก่อนหน้าที่ให้ทำภาพด้วย Photoshop แต่ถ้าสร้าง ตัวแก้ไขป้าย ไว้ในแอปได้ ก็น่าจะดีกว่า เพราะจะตัดวงจร “เดาว่าจะดูเป็นอย่างไรในสภาพแวดล้อม → ส่งออกเป็น PDF → อัปโหลดเข้า DB → ตรวจดูของจริง” ออกไปได้
    ถึงอย่างไรก็คงไม่ได้มีความหมายมากนัก เพราะไม่มีทีม business development หรือการตลาดที่เข้าใจแต่การขายบริการ ไม่ใช่ผลิตภัณฑ์

  • ผมกำลังมองหาของแบบนี้สำหรับโปรเจกต์ของผม https://htwins.net/scale2 และงานอื่น ๆ ที่ใช้ SVG หรือ Canvas อยู่

    • อยากอ่าน บันทึกการสร้าง ว่าทำสิ่งนี้ขึ้นมาอย่างไรจริง ๆ
  • ถ้ากำลังปวดหัวกับ Flexbox ก็มีเครื่องมือที่ช่วยทำให้ขั้นตอนง่ายขึ้น เพื่อไม่ต้องกังวลกับหลายพร็อพเพอร์ตีเวลาสร้างเลย์เอาต์แบบ responsive: https://flexboxcss.com

    • นี่เป็นตัวอย่างแรกของไซต์จริงที่ผมเห็นว่าใช้ ดีไซน์แบบนิวมอร์ฟิก รสนิยมดี และผมยังไม่เคยเห็นในงานจริงมาก่อน
  • ยอดเยี่ยม เครื่องมือแบบนี้สำคัญมากเพราะทำให้ กล่องวิเศษ ที่ชื่อว่า browser rendering engine เข้าใจได้มากขึ้น
    หากเราสร้างสเปกที่เครื่องอ่านได้อย่างสมบูรณ์สำหรับการเรนเดอร์ HTML และ CSS ได้ ก็น่าจะสร้าง renderer ออกมาได้ พฤติกรรมเฉพาะของแต่ละเบราว์เซอร์อาจวางเป็นส่วนขยายทับขึ้นไปได้ อยากให้สิ่งอย่าง https://github.com/tawesoft/html5spec กลายเป็นรูปแบบที่ใช้กับเอนจินจริงได้

    • เห็นสิ่งนี้แล้วนึกถึง Ladybird ว่าเป็นเบราว์เซอร์ที่กำลังเขียนขึ้นใหม่ตั้งแต่ต้น และจริง ๆ แล้วมันก็มีประโยชน์มากในการตรวจสอบว่าสเปกไม่มีบั๊กหรือไม่
  • ค่อนข้างใกล้กับสิ่งที่ช่วงนี้กำลังสงสัยอยู่ ผมกำลังคิดว่าจะใช้ CSS และ SVG เป็น ชั้น abstraction เหนือไลบรารีกราฟิกและ UI ได้หรือไม่
    เพิ่งเคยได้ยิน node-canvas แต่ดูเหมือนจะเติมเต็มส่วนการวาดให้ได้ เครื่องมือนี้ดูจะรับหน้าที่ส่วนเลย์เอาต์ ซึ่งเป็นทั้งหมดที่ผมต้องการจากไลบรารี UI ได้
    ก็สงสัยเหมือนกันว่าการ implement CSS นั้นยากแค่ไหน ได้ยินมาว่าค่อนข้างซับซ้อน

    • ยังมีโปรเจกต์อีกตัวชื่อ Sciter ที่ใช้ CSS เพื่อ target ไลบรารีกราฟิกเนทีฟ: https://sciter.com
      การ implement CSS นั้นยาก แต่กำแพงที่ใหญ่ที่สุดคือความรู้ไม่ได้ถูกเปิดเผยให้เห็นชัดเจน
      ส่วนที่ยากที่สุดคือ เลย์เอาต์ข้อความ การจัดการ glyph และการวนย้อนทางเพื่อ RTL ทำให้ปวดหัว และการตัดบรรทัดก็ซับซ้อนจริง ๆ ยิ่งยากขึ้นเพราะความรู้ที่ต้องใช้ไม่ได้ถูกรวบรวมไว้ในที่เดียว
      หลังจากทำ block layout เสร็จในช่วงแรกแล้ว ผมต้องใช้เวลาหลายปีทำงานแค่สัปดาห์ละไม่กี่ชั่วโมง เพื่อเรียนรู้รายละเอียดของ text shaping และ itemization รวมถึงสิ่งที่ควรทำและไม่ควรทำ หลายส่วนเรียนรู้จากการอ่านซอร์สโค้ดของ Pango [1] และที่เหลือก็ปะติดปะต่อจากการค้นหา Google
      นอกเหนือจากนั้น สเปกของ W3C ครอบคลุมแทบทุกอย่าง มาตรฐาน CSS2 [2] เป็นหนึ่งในเอกสารที่สวยงามที่สุดเท่าที่ผมเคยอ่านมา มันสอดคล้องภายใน กระชับ และเป็นผลลัพธ์จากการไตร่ตรองและลองผิดลองถูกมาหลายปี CSS3 ก็ยอดเยี่ยมเช่นกัน แต่ CSS2 คือรากฐานของทุกอย่าง
      [1] https://gitlab.gnome.org/GNOME/pango/
      [2] https://www.w3.org/TR/CSS22/
  • เป็นการมีส่วนช่วยต่อโลกอย่างยิ่ง ดูเหมือนกรณีคลาสสิกที่ทุกคนคิดว่า “ใครสักคนควรทำ $X” แต่ไม่มีใครลงมือทำ
    ในฐานะคนที่ชอบใช้ CSS สำหรับเลย์เอาต์ ช่วงนี้ผมพึ่งพา Flexbox และ Grid เป็นหลัก เข้าใจได้เต็มที่ว่ายังไม่รองรับ แต่อยากรู้ว่ามีแผนจะรองรับในสักวันไหม ถ้ามี คนอื่น ๆ จะช่วยได้อย่างไร?

  • สุดยอดจริง ๆ คนส่วนใหญ่คงไม่รู้ว่าการแปลง HTML เป็น PNG ด้วยโปรแกรมนั้นยากแค่ไหน
    คุณจะเจอปัญหาเล็ก ๆ นับไม่ถ้วนจาก ความแตกต่างระหว่าง Node กับเบราว์เซอร์ หรือ ความแตกต่างระหว่าง HTML กับ Canvas

  • ดูมีประโยชน์ นึกภาพไม่ออกเลยว่าต้องใช้แรงงานมากแค่ไหนในการทำให้เข้าใจ CSS ก่อน แล้วสร้าง layout engine ขึ้นมาบนนั้น