ตัวเลือกแบบอักษรตัวแปรเพิ่มเติมสำหรับแบบอักษร UI ระบบ macOS ใน Chromium 83

Catalina นำแบบอักษรระบบที่ใช้ตัวแปรใหม่มาใช้กับ macOS

อดัม อาร์ไกล์
อดัม อาร์ไกล์
โดมินิก โรทส์เชส
Dominik Röttsches

ส่วน "system-ui" ของข้อกำหนดโมดูล CSS Fonts Module ระดับ 4 กำหนดคีย์เวิร์ด system-ui ตัวอักษรที่ช่วยให้นักพัฒนาซอฟต์แวร์สามารถใช้แบบอักษรเริ่มต้นในตัว ที่ได้รับการเพิ่มประสิทธิภาพติดเทอร์โบ มีการแปล คุณภาพสูงมาก ไม่จำเป็นต้องดาวน์โหลดในเว็บไซต์และแอปของตนโดยตรง

body {
  font-family: system-ui;
}

ตัวเลือกแบบอักษรนี้จะคล้ายกับการพูดว่า "ใช้แบบอักษรระบบเริ่มต้นสำหรับภาษาปัจจุบันของผู้ใช้รายนี้"

ใน macOS แบบอักษร system-ui คือ San Francisco ซึ่งเป็นแบบอักษรที่ทีมออกแบบได้คัดกรอง ทดสอบ และเพิ่งอัปเกรด ก่อนอื่นเราจะพูดถึงฟีเจอร์แบบอักษรใหม่ๆ ที่น่าสนใจสำหรับ Catalina จากนั้นเราจะพูดถึงข้อบกพร่อง 2-3 รายการและวิธีที่วิศวกร Chromium แก้ปัญหา

โพสต์นี้จะถือว่าคุณคุ้นเคยกับแบบอักษรตัวแปรอยู่แล้ว หากไม่มี โปรดดูข้อมูลเบื้องต้นเกี่ยวกับแบบอักษรตัวแปรบนเว็บ และวิดีโอด้านล่าง

ความเข้ากันได้กับเบราว์เซอร์

ในขณะที่เขียน system-ui ได้รับการสนับสนุนจาก Chromium (ตั้งแต่ 56), Edge (ตั้งแต่ 79), Safari (ตั้งแต่ 11 เป็นต้นไป) และจาก Firefox (ตั้งแต่ 43) แต่ใช้คีย์เวิร์ด -apple-system ดูข้อมูลอัปเดตได้ที่ฉันจะใช้แบบอักษรตัวแปรได้ไหม

พลังใหม่

ความสามารถใหม่ที่ Catalina นำมาใช้กับแบบอักษรของระบบจะเปิดให้บริการแก่นักพัฒนาเว็บตั้งแต่ Chromium 83 เป็นต้นไป แบบอักษร system-ui มีการตั้งค่าตัวแปรเพิ่มขึ้น ได้แก่ การปรับขนาดออปติคัลและการปรับน้ำหนักแบบไม่ซ้ำกัน 2 แบบ ดังนี้

โมฮาวี
h1 {
  font-family: system-ui;
  font-weight: 700;
  font-variation-settings:
    'wght' 750
  ;
}

คาตาลินา
h1 {
  font-family: system-ui;
  font-weight: 700;
  font-variation-settings:
    'wght' 750,
    'opsz' 20,
    'GRAD' 400,
    'YAXS' 400
  ;
}

ใน Mojave ระบบจะใช้ system-ui เป็นแบบอักษรตัวแปรที่มีการตั้งค่า wght เท่านั้น ส่วน system-ui ใน Catalina เป็นแบบอักษรตัวแปรที่มีการตั้งค่า wght, opsz, GRAD และ YAXS

ดูเหมือนเราจะมีโอกาสได้ออกแบบการปรับปรุงที่ก้าวหน้าไปเรื่อยๆ นะ คุณสามารถเจาะลึกรายละเอียดปลีกย่อยของแบบอักษรของระบบได้ตามต้องการ

wght

ยอมรับน้ำหนักแบบอักษรระหว่าง 0 ถึง 900 และใช้กับอักขระทั้งหมดเท่าๆ กัน

/* 0-900 */
font-variation-settings: 'wght' 750;

opsz

การปรับขนาดออปติคัลคล้ายกับการเว้นช่องไฟหรือระยะห่างตัวอักษร แต่ระยะห่างนั้นดำเนินการโดยสายตามนุษย์แทนที่จะเป็นทางคณิตศาสตร์ ค่า 19 หรือต่ำกว่าเป็นค่าสำหรับการเว้นระยะห่างระหว่างข้อความและเนื้อหา ส่วน 20 หรือมากกว่าเป็นค่าสำหรับการเว้นวรรคส่วนหัวและชื่อเรื่องที่แสดงเว้นวรรค

/* 19 or 20 */
font-variation-settings: 'opsz' 20;

GRAD

คล้ายกับน้ำหนัก แต่ไม่มีการสัมผัสกับระยะห่างในแนวนอน ยอมรับค่าระหว่าง 400 ถึง 1000

/* 400-1000 */
font-variation-settings: 'GRAD' 500;

YAXS

ขยายรูปอักขระในแนวตั้ง ยอมรับค่าระหว่าง 400 ถึง 1000

/* 400-1000 */
font-variation-settings: 'YAXS' 500;

การรวมตัวเลือก

เราสามารถปรับแต่งการตั้งค่าแบบอักษรให้เป็นตัวหนาตามตัวเลือกของเรา หรือลองใช้ชุดค่าผสมอื่นๆ ที่น่าสนใจได้โดยใช้ CSS เพียงไม่กี่บรรทัด ดังนี้

font-weight: 700;
font-weight: bold;
font-variation-settings: 'wght' 750, 'YAXS' 600, 'GRAD' 500, 'opsz' 20;

และเช่นเดียวกัน ผู้ใช้ Chromium ใน macOS จะเห็นน้ำหนัก 750 ที่กำหนดเองและการปรับแต่งอื่นๆ สนุกๆ ของคุณ 👍

สนามเด็กเล่น

คลิกรีมิกซ์เพื่อแก้ไขในภาพแตกด้านล่างเพื่อรับสำเนาของ Glitch ที่แก้ไขได้ จากนั้นแก้ไขตัวเลือก font-variation-settings ใหม่เพื่อดูผลกระทบต่อแบบอักษร โปรดทราบว่ากลิทช์นี้จะทำงานเฉพาะในกรณีที่คุณใช้อุปกรณ์ macOS Catalina

macOS 10.15 เพิ่มฟีเจอร์ใหม่ในแบบอักษรของระบบและใน macOS 10.15 ระบบได้บันทึกข้อบกพร่องที่ยุ่งยากของ system-ui ไว้ในเครื่องมือติดตามข้อบกพร่องของ Chromium สงสัยว่าเกี่ยวข้องกันหรือเปล่า

ภาคผนวก: การถดถอยของ system-ui

เรื่องราวนี้เริ่มต้นด้วยข้อบกพร่องอื่น ซึ่งก็คือ #1005969 กรณีนี้เกิดขึ้นกับ macOS 10.15 เนื่องจากระยะห่างของแบบอักษร system-ui ดูแคบและอัดแน่น

การเปรียบเทียบ 2 ย่อหน้าจากหน้ากลุ่มของ Facebook ด้านซ้ายคือ Chrome ส่วนด้านขวาคือ Safari ส่วน Chrome คือระยะห่างน้อยแต่แคบกว่าเล็กน้อย
Chrome ทางด้านซ้าย (การติดตามที่แน่นขึ้น), Safari ทางด้านขวา (ระยะห่างระหว่างออปติคัลที่ดียิ่งขึ้น)

ที่มา

ใน macOS 10.14 คุณสังเกตเห็นหรือไม่ว่าย่อหน้าหรือส่วนหัว "สแนป" เป็นแบบอักษรที่มีรูปลักษณ์ต่างกันอย่างไรเมื่อปรับขนาดขึ้นหรือลง

ใน Mojave (macOS 10.14) แบบอักษร system-ui จะสลับระหว่างแบบอักษร 2 แบบตามขนาดแบบอักษรเป้าหมาย macOS ใช้ "San Francisco Text" เมื่อข้อความอยู่ภายใต้ 20px เมื่อข้อความมีขนาด 20px ขึ้นไป macOS จะใช้ "San Francisco Display" การปรับขนาดออปติคัลสร้างขึ้นจากแบบคงที่โดยแบ่งเป็นแบบอักษร 2 แบบ

Catalina (macOS 10.15) ได้จัดส่งแบบอักษรร่วมแบบใหม่สำหรับซานฟรานซิสโก ไม่ต้องจัดการ "ข้อความ" และ "ดิสเพลย์" อีกต่อไป และยังได้รับการตั้งค่ารูปแบบใหม่ opsz ตามที่อธิบายไว้ก่อนหน้านี้ด้วย

h1 {
  font-variation-settings: 'opsz' 20;
}

ขออภัย ค่าเริ่มต้น opsz ในแบบอักษร Catalina ใหม่คือ 20 และวิศวกรของ Chromium ไม่ได้เตรียมพร้อมที่จะใช้ opsz กับแบบอักษรของระบบ ซึ่งส่งผลให้ขนาดเล็กแสดงผลที่แคบเกินไป

ในการแก้ไขปัญหานี้ Chromium ต้องใช้ opsz กับแบบอักษรของระบบอย่างถูกต้อง ซึ่งส่งผลให้ปัญหา #1005969 ได้รับการแก้ไข ชนะเลิศ! หรือว่าคือ...

ยังไม่เสร็จ

ปัญหาอาจเกิดขึ้นเมื่อ Chromium ใช้ opsz แต่มีบางอย่างทำงานผิดปกติ แบบอักษรของระบบใน Mac มีตารางแบบอักษรเพิ่มเติมชื่อว่า trak ซึ่งจะปรับแต่งระยะห่างในแนวนอน ระหว่างการแก้ไข วิศวกร Chromium พบว่าใน macOS เมื่อดึงข้อมูลเมตริกแนวนอนจากออบเจ็กต์ CTFontRef เมตริก trak ได้นําไปพิจารณาในผลลัพธ์ของเมตริกแล้ว ไลบรารีการกำหนดรูปแบบ HarfBuzz ของ Chromium ต้องการเมตริกที่ค่า trak ยังไม่ได้เป็นปัจจัยพิจารณา

การแสดง UI ของระบบ รวมถึงน้ำหนักตัวอักษรและรูปแบบทั้งหมดในรายการ โดยครึ่งหนึ่งไม่ได้ใช้น้ำหนักที่แตกต่างกัน
ซ้าย: ใช้น้ำหนักตัวหนาสำหรับขนาดแบบอักษร 19 หรือต่ำกว่า ขวา: ขนาดแบบอักษร 20 ขึ้นไปจะไม่มีการจัดรูปแบบตัวหนา

สำหรับภายใน Skia (ไลบรารีกราฟิก ไม่ใช่แบบอักษรที่มีชื่อเดียวกัน) จะใช้ทั้งคลาส CGFontRef จาก CoreGraphics และคลาส CTFontRef จาก CoreText เนื่องจากออบเจ็กต์เหล่านั้นต้องมี Conversion ภายใน (ใช้เพื่อการรักษาความเข้ากันได้แบบย้อนหลังและเข้าถึง API ที่จำเป็นของทั้ง 2 คลาส) Skia จะลดข้อมูลน้ำหนักในบางสถานการณ์ และแบบอักษรตัวหนาจะหยุดทำงาน ซึ่งติดตามได้ในปัญหา #1057654

Skia ยังต้องรองรับ macOS 10.11 อยู่เนื่องจาก Chromium ยังคงรองรับอยู่ ในวันที่ 10.11 แบบอักษร "San Francisco Text" และ "San Francisco Display" ไม่มีแม้แต่แบบอักษรที่เปลี่ยนแปลงได้ แต่แต่ละแบบจะมีแบบอักษรแยกกันสำหรับทุกๆ น้ำหนักที่มี ก่อนหน้านี้รหัสรูปอักขระทั้ง 2 รหัสไม่ตรงกัน ดังนั้น ถ้า Skia จัดรูปแบบข้อความ (แปลงข้อความเป็นรูปอักขระที่สามารถวาดได้) ด้วย "San Francisco Text" ข้อความนี้จะเป็นคำที่ไม่มีความหมายหากวาดด้วย "San Francisco Display" และในทางกลับกัน และแม้ว่า Skia เพิ่งจะขอขนาด macOS อื่นก็อาจเปลี่ยนไปใช้เครื่องอื่นด้วย เป็นไปได้ที่จะใช้แบบอักษรอันใดอันหนึ่งและเพียงแค่ปรับขนาด (ใช้เมทริกซ์เพื่อปรับขนาดแทนการขอขนาดใหญ่) แต่ CoreText มีปัญหาเรื่องที่ไม่ปรับขนาดรูปอักขระ sbix (อีโมจิสี) ขึ้น (ลดลงเท่านั้น) มันซับซ้อนมากกว่านั้น ดูเหมือนว่า CoreText จะจำกัดขอบเขตในแนวตั้งหลังจากแอปพลิเคชันเมทริกซ์ ซึ่งดูเหมือนว่าจะเกี่ยวข้องกับการวาดอีโมจิในมุม 45 องศาไม่ได้ ไม่ว่าในกรณีใดก็ตาม หากต้องการให้อีโมจิแสดงขนาดใหญ่ คุณต้องทำสำเนาแบบอักษรเพื่อรับเวอร์ชันขนาดใหญ่

ดังนั้น เพื่อสร้างสำเนาของออบเจ็กต์ CTFont ขนาดต่างๆ ภายในขณะที่มีการใช้ข้อมูลแบบอักษรพื้นฐานเดียวกัน Chromium จะดึง CGFont ออกจาก CTFont และสร้าง CTFont ใหม่จาก CGFont (ออบเจ็กต์ CGFont มีขนาดไม่ขึ้นอยู่กับขนาด การสลับแบบวิเศษจะเกิดขึ้นที่ระดับ CoreText) ทั้งหมดนี้ใช้งานได้ดีจนถึงวันที่ 10.154 ในเวลา 10:15 น. - การเดินทางไป-กลับนี้สูญเสียข้อมูลมากเกินไป ซึ่งส่งผลให้เกิดปัญหาเรื่องน้ำหนัก Flutter พบปัญหาเรื่องน้ำหนักและมีการแก้ไขทางเลือกสำหรับการปรับขนาดเพื่อสร้าง CTFont ใหม่จาก CTFont เดิมโดยตรง ในขณะที่ควบคุมขนาดออปติคัลโดยตรงโดยใช้แอตทริบิวต์เก่าแต่ไม่มีข้อมูลใน CoreText การทำงานนี้ทำให้ทุกอย่างทำงานได้ในเวอร์ชัน 10.11 และแก้ไขปัญหาอื่นๆ (เช่น การตั้งค่าขนาดออปติคัลเป็นค่าเริ่มต้นอย่างชัดเจน)

แต่วิธีนี้จะรักษา "เวทมนตร์" ของ CoreText ไว้ในแบบอักษรได้มากกว่า ดูเหมือนว่าหนึ่งในนั้นยังคงปรับเปลี่ยนความก้าวหน้าของรูปอักขระด้วยวิธีอื่นที่ไม่ใช่เพียงตาราง trak (แอปพลิเคชันที่ Chromium ได้พยายามระงับแอตทริบิวต์อีกรายการที่ไม่ได้ระบุไว้อยู่แล้ว)

CGFont ไม่ได้ทำอะไรกับ "เวทมนตร์" นี้เลย บางที Chromium อาจได้ CGFont สำหรับCTFont แล้วใช้เพื่อรับความก้าวหน้าไหม ต้องขออภัยด้วยที่จะไม่สามารถใช้งานได้ เพราะ CoreText มีการล้อเลียนกับแบบอักษรในลักษณะอื่นเช่นกัน เช่น ทำให้อีโมจิขนาดเล็กใหญ่กว่าที่คุณขอไว้จริงเล็กน้อย (ระบบจะเพิ่มขนาดอีกเล็กน้อย) CGFont ไม่ทราบเรื่องนี้ คุณจึงลงเอยด้วยอีโมจิที่ใช้รูปแบบ sbix ของคุณอยู่ใกล้กันเกินไปเนื่องจากคุณต้องวัดที่ขนาดเดียว แต่ CoreText จะวาดให้ใหญ่ขึ้นในระดับหนึ่ง Chromium ต้องการความก้าวหน้าของ CTFont แต่ก็ต้องการสิ่งที่ไม่ต้องติดตาม และไม่ควรติดตามอื่นใด

เนื่องจากการแก้ไขปัญหาเรื่องระยะห่างจำเป็นต้องใช้ชุดการแก้ไข Blink และ Skia ที่เชื่อมต่อถึงกัน วิศวกร Chromium จึง "แค่เปลี่ยนกลับ" เพื่อแก้ปัญหานี้ไม่ได้ วิศวกร Chromium ยังได้ลองใช้แฟล็กเวอร์ชันอื่นสำหรับการเปลี่ยน Codepath ที่เกี่ยวข้องกับแบบอักษรใน Skia ซึ่งแก้ปัญหาแบบอักษรตัวหนา แต่ปัญหาเรื่องระยะห่างกลับลดลง

การแก้ไข

สุดท้ายแล้ว Chromium ต้องการแก้ไขทั้ง 2 อย่าง ขณะนี้ Chromium หันไปใช้ฟังก์ชันเมตริกแบบอักษร OpenType แบบอักษรในตัวของ HarfBuzz เพื่อดึงเมตริกแนวนอนจากข้อมูลไบนารีในตารางแบบอักษรของระบบโดยตรง เมื่อใช้ตัวเลือกนี้ Chromium จะเลี่ยง CoreText และ Skia เมื่อแบบอักษรมีตาราง trak (ยกเว้นเมื่อเป็นแบบอักษรอีโมจิ)

การแสดง UI ของระบบ รวมถึงน้ำหนักตัวอักษรและรูปแบบทั้งหมดในรายการ ครึ่งก่อนหน้านี้ที่ทำไม่ได้ดูดีมากเลย

ในระหว่างนี้ คุณยังคงมีปัญหาสกี #10123 เพื่อติดตามการแก้ปัญหานี้อย่างเต็มรูปแบบใน Skia และกลับไปใช้ Skia เพื่อเรียกข้อมูลเมตริกแบบอักษรระบบจากที่นั่น แทนการแก้ไขปัจจุบันที่ดำเนินการผ่าน HarfBuzz