Ascender — بخشی از حرف کوچک است که بالای ارتفاع حروف کوچک (x-height) قرار میگیرد. در سیریلیک این عناصر حروف be، ef، ve هستند، در لاتین — «b»، «d»، «f»، «h»، «k»، «l»، «t». طول ascender در فانتهای مختلف متفاوت است و به طور حیاتی بر ریتم خط تأثیر میگذارد. به استناد به Google Fonts Knowledge Guide (2025)، فانتهای با ascender بلند معمولاً باشکوهتر تلقی میشوند، اما برای خواندن راحت در دستگاههای موبایل به فاصله خطوط بیشتری نیاز دارند.
نکات کلیدی
Ascender (عنصر بالای بیرونزده) — بخشی از گلیف کوچک است که در بالای خط x-height قرار دارد. در تیپوگرافی، x-height ارتفاع حروف کوچک بدون عناصر بیرونزده است — مانند ارتفاع حروف «x» یا «o». Ascender آنجا آغاز میشود که x-height پایان مییابد و تا خط ascender-line — بالاترین مرز فانت — ادامه مییابد.
همه حروف کوچک ascender ندارند. به عنوان مثال، حروف «a»، «e»، «o»، «n»، «s» کاملاً در ارتفاع x-height قرار میگیرند. اما حروف be، ve، de، ef در سیریلیک و «b»، «d»، «f»، «h»، «k» در لاتین شامل عناصر بیرونزده هستند که بالاتر میروند. حروف بزرگ (کپیتال) نیز میتوانند به خط ascender-line برسند، اما ارتفاع آنها cap-height نامیده میشود و در معنای مستقیم ascender محسوب نمیشود.
به استناد به Adobe Typekit — Glossary of Typography (2024)، نسبت ascender به x-height یکی از ویژگیهای کلیدی فانت است. فانتهایی با ascender بلند نسبت به x-height (مانند فانتهای سبک قدیمی مانند Garamond) حس زیبایی و سبکی ایجاد میکنند. فانتهای با ascender پایین (مانند گروتسکهای هندسی مانند 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 قرار دارد. هر دو مقدار با واحدهای قراردادی — FUnits (Font Units) — اندازهگیری میشوند، که معمولاً 1000 یا 2048 FUnits مربوط به ارتفاع چهارگوش ام است.
# خواندن متریکهای 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 در دسترس است. این ویژگی فاصله از خط پایه تا بالای خط (ascender-line) را به پوینت برمیگرداند. متریک نه تنها ascender خود فانت، بلکه حاشیه اضافی (leading) را نیز شامل میشود که توسط طراح فانت برای بهبود خوانایی اضافه شده است.
// دریافت 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 دقیق برای ایجاد چیدمانهای متن سفارشی ضروری است — مانند رندر متن با اندازههای مختلف در یک خط یا تراز متن نسبت به مختصات دلخواه روی Canvas. به استناد به objc.io — Core Text and TextKit (2025)، نادیده گرفتن ascender در رندر سفارشی یکی از دلایل مکرر بریدگی عناصر بالای حروف be، ef و «d» است.
در Android، متریکهای ascender از طریق کلاسهای Paint.FontMetrics و Paint.FontMetricsInt در دسترس هستند. روش Paint.getFontMetrics() مقادیر ascent (فاصله از خط پایه تا بالای گلیف) و top (فاصله از خط پایه تا مرز بالای خط با حاشیه leading) را برمیگرداند. مقدار ascent در سیستم مختصات Android همواره منفی است، جایی که خط پایه مختصات 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 در دسترس هستند. پس از رسم متن، میتوان خطی با متریکهای هر سطر، از جمله موقعیت خط پایه و اندازههای 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 — 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 فاصله از خط پایه تا بالای خط، descender فاصله از خط پایه تا پایین (منفی)، 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–4 pt بسته به اندازه و فانت افزایش دهید.
رایجترین اشتباه — این فرض که همه فانتها در همان اندازه، ascender یکسانی دارند. در عمل، ascender میتواند تا 30% بین فانتها متفاوت باشد. اگر طراح در طرح از SF Pro با ascender 15 pt (در اندازه 16) استفاده کرده باشد و توسعهدهنده Inter را با ascender 17 pt متصل کرده باشد — بلوکهای متنی جابجا شده و ریتم عمودی را مخلل میکنند.
به استناد به UX Collective — 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 است. برای دریافت مقادیر دقیق در دستگاههای مختلف، این کد را روی دستگاه واقعی اجرا کنید — متریکها میتوانند در نسخههای مختلف iOS کمی متفاوت باشند. برای فانتهای سفارشی، نتیجه به جداول داخلی آنها بستگی دارد.
در نمایشگرهای کوچک (گوشیهای هوشمند با قطر تا 5 اینچ) حروف با ascender بخش قابل توجهی از فضای عمودی را اشغال میدهند. اگر ascender نسبت به اندازه خیلی بلند باشد، حروف be و ef میتوانند با عناصر رابط ادغام شوند. فانتهایی با ascender متعادل (Roboto، SF Pro) برای نمایشگرهای کوچک بهینهشده اند، و فانتهای با ascender بلند (Garamond) برای تبلتها مناسبتر هستند.
سادهترین راه — نمایش رشته آزمایشی «be-ve-ef-iy-dhl» در هر عنصر متنی برنامه و بررسی اینکه حروف از مرزهای کنتینر خارج نشوند. برای بررسی خودکار، از آزمایشهای snapshot با این رشته استفاده کنید. در iOS از Debug View Hierarchy و در Android از Layout Inspector برای بازرسی تصویری استفاده کنید.
بله، ascender میتواند کمی تغییر کند بین Regular، Bold و Italic یک خانواده. معمولاً تفاوت از 2–3% تجاوز نمیکند، اما در فانتهای تزیینی میتواند به 10% برسد. متریکهای هر صورت را جداگانه بررسی کنید، ویژه برای عناوین (Bold) و متن اصلی (Regular) — آنها ممکن است در همان اندازه به line-height مختلفی نیاز داشته باشند.
نتیجهگیری
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید