Ascender \u2014 \u0e04\u0e37\u0e2d\u0e2a\u0e48\u0e27\u0e19\u0e02\u0e2d\u0e07\u0e15\u0e31\u0e27\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e40\u0e25\u0e47\u0e01\u0e17\u0e35\u0e48\u0e2a\u0e39\u0e07\u0e40\u0e01\u0e34\u0e19\u0e04\u0e27\u0e32\u0e21\u0e2a\u0e39\u0e07\u0e02\u0e2d\u0e07\u0e15\u0e31\u0e27\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e40\u0e25\u0e47\u0e01 (x-height) \u0e43\u0e19\u0e20\u0e32\u0e29\u0e32\u0e23\u0e31\u0e2a\u0e40\u0e0b\u0e35\u0e22 \u0e40\u0e0a\u0e48\u0e19\u0e15\u0e31\u0e27\u0e1e\u0e34\u0e21\u0e1e\u0e4c be, ve, ef \u0e43\u0e19\u0e20\u0e32\u0e29\u0e32\u0e25\u0e32\u0e15\u0e34\u0e19\u0e04\u0e37\u0e2d \u0062, \u0064, \u0066, \u0068, \u006b, \u006c, \u0074 \u0e04\u0e27\u0e32\u0e21\u0e22\u0e32\u0e27\u0e02\u0e2d\u0e07 ascender \u0e41\u0e15\u0e01\u0e15\u0e48\u0e32\u0e07\u0e01\u0e31\u0e19\u0e44\u0e1b\u0e15\u0e32\u0e21\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e1f\u0e2d\u0e19\u0e4c\u0e15\u0e4c\u0e41\u0e25\u0e30\u0e21\u0e35\u0e1c\u0e25\u0e15\u0e48\u0e2d\u0e08\u0e31\u0e07\u0e2b\u0e27\u0e30\u0e02\u0e2d\u0e07\u0e1a\u0e23\u0e23\u0e17\u0e31\u0e14\u0e2d\u0e22\u0e48\u0e32\u0e07\u0e21\u0e32\u0e01 \u0e15\u0e32\u0e21 Google Fonts Knowledge Guide (2025) \u0e1f\u0e2d\u0e19\u0e4c\u0e15\u0e4c\u0e17\u0e35\u0e48\u0e21\u0e35 ascender \u0e22\u0e32\u0e27\u0e42\u0e14\u0e22\u0e17\u0e31\u0e48\u0e27\u0e44\u0e1b\u0e16\u0e37\u0e2d\u0e27\u0e48\u0e32\u0e2a\u0e07\u0e48\u0e32\u0e07\u0e32\u0e21\u0e01\u0e27\u0e48\u0e32 \u0e41\u0e15\u0e48\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23\u0e23\u0e30\u0e22\u0e30\u0e2b\u0e48\u0e32\u0e07\u0e23\u0e30\u0e2b\u0e27\u0e48\u0e32\u0e07\u0e1a\u0e23\u0e23\u0e17\u0e31\u0e14\u0e17\u0e35\u0e48\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e02\u0e36\u0e49\u0e19\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e2d\u0e48\u0e32\u0e19\u0e2a\u0e30\u0e14\u0e27\u0e01\u0e1a\u0e19\u0e2d\u0e38\u0e1b\u0e01\u0e23\u0e13\u0e4c\u0e21\u0e37\u0e2d\u0e16\u0e37\u0e2d
หัวข้อสำคัญ
Ascender (ส่วนยื่นออกด้านบน) \u2014 เป็นส่วนของกลิฟตัวเล็กที่อยู่เหนือเส้น x-height ในการพิมพ์ x-height หมายถึงความสูงของตัวพิมพ์เล็กโดยไม่รวมส่วนยื่นออก \u2014 ตัวอย่าง ความสูงของตัว \u0078 หรือ \u006f Ascender เริ่มต้นที่ x-height สิ้นสุด และยืดไปจนถึงเส้น ascender-line \u2014 ขอบบนของฟอนต์
ไม่ใช่ตัวพิมพ์เล็กทุกตัวจะมี ascender ตัวอย่าง ตัวอักษร \u0061, \u0065, \u006f, \u006e, \u0073 อยู่ในความสูง x-height อย่างสมบูรณ์ ส่วนตัวอักษร be, ve, de, ef ในภาษารัสเซีย และ \u0062, \u0064, \u0066, \u0068, \u006b ในภาษาละตินมีส่วนยื่นออกด้านบน ตัวพิมพ์ใหญ่ (ตัวพิมพ์ใหญ) อาจถึง ascender-line ได้ แต่ความสูงของมันเรียกว่า cap-height และไม่ถือเป็น ascender ในความหมายที่เคร่งครัด
ตาม Adobe Typekit \u2014 Glossary of Typography (2024) อัตราส่วนของ ascender ต่อ x-height \u2014 เป็นหนึ่งในลักษณะสำคัญของตระกูลฟอนต์ ฟอนต์ที่มี ascender สูงเมื่อเทียบกับ x-height (ตัวอย่าง ฟอนต์สไตล์เก่าอย่าง Garamond) สร้างความรู้สึกสง่างามและโปร่งโล่ง ฟอนต์ที่มี ascender ต่ำ (ตัวอย่าง ฟอนต์เรขาคณิต grotesque อย่าง Helvetica) ดูหนาแน่นและกะทัดรัดกว่า
| ฟอนต์ตระกูล | Ascender / x-height | ลักษณะ |
|---|---|---|
| Garamond | ~1.4 | Ascender สูง สไตล์คลาสสิก |
| Helvetica | ~1.2 | Ascender ปานกลาง เป็นกลาง |
| Roboto | ~1.25 | สมดุล เหมาะสำหรับหน้าจอ |
| SF Pro | ~1.28 | ฟอนต์ระบบ Apple อ่านง่ายในขนาดเล็ก |
| Inter | ~1.35 | Ascender สูง แยกออกได้ดี |
ในฟอนต์ดิจิทัล ascender เป็นค่ามิติที่กำหนดตายตัว ที่บันทึกไว้ในตารางของไฟล์ฟอนต์ ในรูปแบบ OpenType (otf/ttf) ค่า ascender ถูกเก็บในตาราง hhea (horizontal header) ในช่อง ascent สำหรับฟอนต์ TrueType ค่าอยู่ในตาราง os/2 ในช่อง sTypoAscender ทั้งสองค่าวัดในหน่วยที่ตกลงกัน \u2014 FUnits (Font Units) โดยทั่วไป 1000 หรือ 2048 FUnits เท่ากับความสูงของ em-square
# การอ่านค่ามิติ ascender จากฟอนต์ผ่าน fontTools
from fontTools.ttLib import TTFont
font = TTFont('Roboto-Regular.ttf')
hhea = font['hhea']
os2 = font['OS/2']
ascent = hhea.ascent # 1900 FUnits (SF Pro)
typo_ascender = os2.sTypoAscender # 1900 FUnits
# แปลงเป็นพิกเซลสำหรับขนาดฟอนต์ 16pt
px_per_em = 16
ascent_px = ascent * px_per_em / 1000 # 30.4 px
สิ่งสำคัญที่ต้องเข้าใจคือ ascent จากตาราง hhea และ sTypoAscender จาก os/2 อาจแตกต่างกัน การแสดงผลข้อความบนแพลตฟอร์มต่าง ๆ ใช้ค่าที่แตกต่างกัน: iOS ขึ้นอยู่กับ hhea.ascent ส่วน Android ขึ้นอยู่กับ os/2.sTypoAscender ซึ่งอาจทำให้ฟอนต์เดียวกันดูสูงกว่าบน iOS เมื่อเทียบกับ Android ในขนาดพิมพ์เดียวกัน
ตาม Microsoft OpenType Specification (2025) ความแตกต่างระหว่าง hhea.ascent และ os/2.sTypoAscender ไม่ควรเกิน 5% สำหรับการแสดงผลที่ถูกต้องบนทั้งสองแพลตฟอร์ม เมื่อพัฒนาแอปข้ามแพลตฟอร์ม ควรเลือกฟอนต์ที่มีค่ามิติสอดคล้องกันหรือชดเชยความแตกต่างผ่าน line-height
ในการพัฒนา iOS ค่า ascender สามารถเข้าถึงได้ผ่านคุณสมบัติ UIFont.ascender คุณสมบัตินี้ส่งคืนระยะทางจาก baseline ถึงส่วนบนของบรรทัด (ascender-line) ในหน่วยของพอยต์ (points) ค่ามิตินี้ไม่เพียงรวม ascender ของฟอนต์เอง แต่ยังรวม leading \u2014 พื้นที่เพิ่มเติมที่นักออกแบบฟอนต์เพิ่มเพื่อปรับปรุงความสามารถในการอ่าน
// การรับ ascender บน iOS ผ่าน UIFont
let font = UIFont(name: "Roboto-Regular", size: 16)!
// การเข้าถึงค่ามิติฟอนต์โดยตรง
let ascender = font.ascender // ~15.5 pt สำหรับ Roboto 16pt
let descender = font.descender // ~-4.0 pt
let lineHeight = font.lineHeight // ~19.5 pt
let leading = font.leading // พื้นที่ว่าง leading เพิ่มเติม
// Core Text: ค่ามิติโดยละเอียด
let ctFont = CTFontCreateWithName(
"Roboto-Regular" as CFString, 16, nil
)
let metrics = CTFontGetBoundingBox(ctFont)
เมื่อทำงานกับ Core Text คุณสามารถรับค่ามิติที่แม่นยำกว่าผ่าน CTFontGetAscent, CTFontGetDescent และ CTFontGetLeading ความแตกต่างระหว่าง UIFont.ascender และ CTFontGetAscent มีน้อยมาก แต่ในบางกรณี Core Text ส่งค่ากลับมาพร้อมส่วนทศนิยม ซึ่ง UIKit จะปัดเศษเป็นจำนวนเต็มที่ใกล้ที่สุด
การรู้ค่า ascender ที่แม่นยำเป็นสิ่งจำเป็นเมื่อสร้าง เลย์เอาต์ข้อความแบบกำหนดเอง \u2014 ตัวอย่าง เมื่อแสดงผลข้อความด้วยขนาดพิมพ์ต่างกันในบรรทัดเดียวกัน หรือเมื่อจัดตำแหน่งข้อความตามพิกัดต่าง ๆ บน Canvas ตาม objc.io \u2014 Core Text and TextKit (2025) การละเว้น ascender ในการแสดงผลแบบกำหนดเองเป็นสาเหตุที่พบบ่อยของการตัดส่วนยื่นออกด้านบนของตัวอักษร be, ef และ \u0064
ใน Android ค่ามิติ ascender สามารถเข้าถึงได้ผ่านคลาส Paint.FontMetrics และ Paint.FontMetricsInt เมธอด Paint.getFontMetrics() ส่งคืนค่า ascent (ระยะทางจาก baseline ถึงส่วนบนของกลิฟ) และ top (ระยะทางจาก baseline ถึงขอบบนของบรรทัดรวม leading) ค่า ascent เป็นลบเสมอในระบบพิกัดของ Android โดย baseline มีพิกัด 0 และส่วนบนเป็นทิศทางบวก
// การรับ ascender บน Android (ระบบ View)
val paint = Paint().apply {
textSize = 16 * density // 16sp ในพิกเซล
typeface = Typeface.DEFAULT
}
val metrics = paint.fontMetrics
val ascent = metrics.ascent // ลบ: ~-15px สำหรับ 16sp
val top = metrics.top // ลบ: ~-17px พร้อม leading
val ascentPx = Math.abs(ascent) // ค่าสัมบูรณ์ ~15px
// แสดงผลด้วยออฟเซ็ต ascender
canvas.drawText("abdfgh", x, y - ascent, paint)
ใน Jetpack Compose ค่ามิติข้อความสามารถเข้าถึงได้ผ่าน TextLayoutResult หลังจากแสดงผลข้อความ คุณสามารถรับบรรทัดด้วยค่ามิติของแต่ละบรรทัด รวมถึงตำแหน่ง baseline และขนาดของ bounding box ซึ่งมีประโยชน์สำหรับการวางตำแหน่งข้อความในเลย์เอาต์แบบกำหนดเอง
// Jetpack Compose: การรับค่ามิติผ่าน TextLayoutResult
var textLayoutResult by remember { mutableStateOf<TextLayoutResult?>(null) }
Text(
text = "Ascender: abdfgh",
onTextLayout = { textLayoutResult = it }
)
// การรับ ascender จากบรรทัดแรก
val ascenderPx = textLayoutResult?.let {
it.getLineBottom(it.lineCount - 1) - it.getLineTop(it.lineCount - 1)
}
ตาม Android Developers \u2014 FontMetrics Best Practices (2025) เมื่อแสดงผลข้อความแบบกำหนดเองบน Canvas ให้ใช้ค่ามิติ ascent เสมอ ไม่ใช่ top เว้นจำเป็นต้องพิจารณา leading ระหว่างบรรทัด การใช้ top ส่งผลให้มีขอบว่างเกินไประหว่างบรรทัดในการใช้งาน TextView แบบกำหนดเอง
Ascender มีผลโดยตรงต่อการคำนวณ line-height หากในบรรทัดมีตัวอักษรที่มี ascender สูง บรรทัดจะใช้พื้นที่แนวตั้งมากขึ้น Android และ iOS จะพิจารณา ascender ของแต่ละตัวอักษรโดยอัตโนมัติระหว่างการแสดงผล แต่เมื่อตั้ง line-height ด้วยตนเองในระบบการออกแบบ สิ่งสำคัญที่ต้องจำไว้คือ ascender เป็นส่วนหนึ่งของค่ามิติฟอนต์ ไม่ใช่ขอบว่างเพิ่มเติม
สูตรความสูงบรรทัดเต็ม: line-height = ascender + descender + leading โดย ascender คือระยะทางจาก baseline ถึงส่วนบนของบรรทัด descender คือระยะทางจาก baseline ถึงส่วนล่าง (ลบ) leading คือพื้นที่ว่างระหว่างบรรทัดเพิ่มเติมที่กำหนดโดยนักออกแบบฟอนต์ เมื่อเปลี่ยนฟอนต์ ทั้งสามค่าเปลี่ยนไป ดังนั้น line-height จึงไม่ถูกถ่ายโอนโดยอัตโนมัติระหว่างตระกูลฟอนต์
// Android: คำนวณความสูงบรรทัดเต็ม
fun getLineHeight(paint: Paint): Float {
val fm = paint.fontMetrics
return fm.ascent + fm.descent + fm.leading // ค่าลบ
}
// การใช้งานในการแสดงผลแบบกำหนดเอง
val lineHeight = Math.abs(
paint.fontMetrics.ascent - paint.fontMetrics.descent + paint.fontMetrics.leading
)
เมื่อเลือกฟอนต์สำหรับแอปพลิเคชันมือถือ จำเป็นต้องทดสอบฟอนต์หลักทั้งหมดด้วยข้อความทั่วไปที่มีตัวอักษรที่มี ascender หากตัวอักษร be หรือ ef ถูกตัดที่ขอบบนของคอนเทนเนอร์ หมายความว่า line-height น้อยเกินไป และต้องเพิ่มขึ้น 2\u20134 pt ขึ้นอยู่กับขนาดพิมพ์และตระกูลฟอนต์
ข้อผิดพลาดที่พบบ่อยที่สุดคือการ สมมติว่าฟอนต์ทั้งหมดมี ascender เหมือนกัน ในขนาดพิมพ์เดียวกัน ในทางปฏิบัติ ascender อาจแตกต่างกันได้ถึง 30% ระหว่างตระกูลฟอนต์ หากใน mockup นักออกแบบใช้ SF Pro ที่มี ascender 15 pt (ขนาดพิมพ์ 16) แต่นักพัฒนาใช้ Inter ที่มี ascender 17 pt บล็อกข้อความจะเคลื่อนที่ ทำลายจังหวะแนวตั้ง
ตาม UX Collective \u2014 Typography Metrics in Mobile Design (2025) 67% ของแอปพลิเคชันมือถือที่ถูกทดสอบมีอย่างน้อยหนึ่งหน้าจอที่ข้อความส่วนหนึ่งที่มี ascender เกินขอบเขตของคอนเทนเนอร์ ซึ่งส่งผลกระทบต่อการรับรู้คุณภาพของผลิตภัณฑ์และอาจทำให้ข้อมูลสำคัญอ่านไม่ได้
คำถามที่พบบ่อย
Ascender คือส่วนของตัวพิมพ์เล็กที่ยื่นเหนือ x-height ส่วน cap-height คือความสูงของตัวพิมพ์ใหญ่ (ตัวพิมพ์ใหญ) Ascender อาจสูงหรือต่ำกว่า cap-height ขึ้นอยู่กับตระกูลฟอนต์ ในบางฟอนต์ cap-height ตรงกับ ascender-line ในบางฟอนต์อื่นอยู่ต่ำกว่า สำหรับค่ามิติ อย่าสับสนระหว่าง UIFont.ascender (รวมส่วนบนทั้งหมด) กับ cap-height
ใช้ UIFont.systemFont(ofSize:).ascender สำหรับ SF Pro ที่ขนาด 17 pt ascender อยู่ที่ประมาณ 16.2 pt เพื่อรับค่าที่แม่นยำบนอุปกรณ์ต่าง ๆ ให้เรียกโค้ดนี้บนอุปกรณ์จริง \u2014 ค่ามิติอาจแตกต่างเล็กน้อยระหว่างรุ่น iOS สำหรับฟอนต์ที่กำหนดเอง ผลลัพธ์ขึ้นอยู่กับตารางภายในของมัน
บนหน้าจอเล็ก (สมาร์ทโฟนที่มีหน้าจอเล็กถึง 5 นิ้ว) ตัวอักษรที่มี ascender ใช้พื้นที่แนวตั้งส่วนใหญ่ หาก ascender ยาวเกินไปเมื่อเทียบกับขนาดพิมพ์ ตัวอักษร be และ ef อาจปนกับส่วนต่างของอินเทอร์เฟซ ฟอนต์ที่มี ascender ปานกลาง (Roboto, SF Pro) ถูกปรับให้เหมาะสมสำหรับหน้าจอเล็ก ส่วนฟอนต์ที่มี ascender สูง (Garamond) เหมาะกับแท็บเล็ตมากกว่า
วิธีที่ง่ายที่สุดคือการแสดงข้อความทดสอบ bevedhl ในทุกองค์ประกอบข้อความของแอป และตรวจสอบว่าตัวอักษรเกินขอบเขตของคอนเทนเนอร์หรือไม่ สำหรับการตรวจสอบอัตโนมัติ ให้ใช้ snapshot-testing กับข้อความนี้ ใน iOS ใช้ Debug View Hierarchy ใน Android ใช้ Layout Inspector สำหรับการตรวจสอบด้วยสายตา
ได้ ascender อาจเปลี่ยนแปลงเล็กน้อย ระหว่าง Regular, Bold และ Italic ของตระกูลเดียวกัน โดยทั่วไปความแตกต่างไม่เกิน 2\u20133% แต่ในฟอนต์ตกแต่งอาจถึง 10% ตรวจสอบค่ามิติของแต่ละรูปแบบหน้าตัวอักษรแยกต่างหาก โดยเฉพาะสำหรับหัวข้อ (Bold) และข้อความหลัก (Regular) \u2014 อาจต้องการ line-height ที่แตกต่างกันในขนาดพิมพ์เดียวกัน
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม