মোবাইল ডেভেলপমেন্টে Descender — সারমর্ম, অর্থ এবং লেআউটের উপর প্রভাব

লেখক: IT Sectr প্রকাশিত: 2026-07-24 পড়ার সময়: 9 মিনিট

Descender একটি ছোট হাতের অক্ষরের সেই অংশ যা ফন্টের বেসলাইন (baseline) এর নিচে প্রসারিত হয়। ল্যাটিন লিপিতে, descender সহ সাধারণ অক্ষরগুলি হল “g”, “j”, “p”, “q”, “y”। Descender-এর দৈর্ঘ্য ফন্টের নিচের প্রসারিত উপাদান নির্ধারণ করে এবং লাইন স্পেসিং গণনার জন্য অত্যন্ত গুরুত্বপূর্ণ: baseline-এর নিচে পর্যাপ্ত স্থান ছাড়া, descender সহ অক্ষরগুলি পরবর্তী লাইনের সাথে সংঘর্ষ করবে। Material Design Type Scale Guidelines (2025) অনুসারে, descender-এর অপর্যাপ্ত বিবেচনা মোবাইল ডিভাইসে বহু-লাইন টেক্সটে লাইন সংঘর্ষের প্রধান কারণগুলির মধ্যে একটি।

মূল পয়েন্ট

  • Descender — অক্ষরের নিচের প্রসারিত উপাদান, baseline-এর নিচে অবস্থিত।
  • মেট্রিক — descender UIFont.descender (iOS) এবং Paint.FontMetrics.descent (Android) এর মাধ্যমে উপলব্ধ।
  • Line-height — descender লাইনের পূর্ণ উচ্চতার গণনায় অন্তর্ভুক্ত হয় এবং লেআউটে বিবেচনার প্রয়োজন।
  • লাইন সংঘর্ষ — descender বিবেচনা না করলে, descender সহ অক্ষরগুলি নিচের লাইনের সাথে সংঘর্ষ করে।
  • ভিন্ন ফন্ট — descender-এর দৈর্ঘ্য টাইপফেসের মধ্যে পরিবর্তিত হয়, যা ভিজ্যুয়াল তালকে প্রভাবিত করে।

টাইপোগ্রাফিতে Descender কী

Descender হল গ্লিফের সেই অংশ যা বেসলাইনের নিচে অবস্থিত। অক্ষরের মূল অংশ baseline-এর উপর অবস্থান করলেও, descender তার বাইরে প্রসারিত হয়ে ফন্টের বৈশিষ্ট্যপূর্ণ আকৃতি তৈরি করে। ল্যাটিন লিপিতে, descender সহ অক্ষরগুলির মধ্যে “g”, “j”, “p”, “q”, “y” অন্তর্ভুক্ত — এদের নিচের উপাদানগুলি লাইনের নিচে নেমে যায়।

Descender-এর গভীরতা baseline থেকে গ্লিফের নিচের প্রান্ত (descender-line) পর্যন্ত দূরত্ব বর্ণনা করে। মানসম্পন্ন ফন্টে, এই দূরত্ব ভারসাম্যপূর্ণ: খুব ছোট descender descender সহ অক্ষরগুলি চিহ্নিত করা কঠিন করে তোলে, অন্যদিকে খুব লম্বা descender লাইনের মধ্যে অত্যধিক খালি স্থান তৈরি করে এবং টেক্সটের ঘনত্ব হ্রাস করে। বিভিন্ন টাইপফেস descender দৈর্ঘ্যে গুরুত্বপূর্ণ পার্থক্য দেখায়।

টাইপফেসDescender / em-sizedescender সহ অক্ষরের উদাহরণ
SF Pro~0.22g, j, p, q, y — ভারসাম্যপূর্ণ প্রসারণ
Roboto~0.24g, j, p — মাঝারি descender
Playfair Display~0.30g, j, p, q — লম্বা আলংকারিক উপাদান
Inter~0.26g, j, p — উল্লেখযোগ্যভাবে baseline-এর নিচে
Noto Sans~0.20g, j — ছোট descender, কমপ্যাক্ট

Google Fonts Metrics Guide (2025) অনুসারে, descender-কে সর্বোত্তম বিবেচনা করা হয় যখন এর গভীরতা পূর্ণ em আকারের (1000 FUnits) 20–25% হয়। 15% এর নিচের মান descender সহ অক্ষরগুলি পৃথক করা কঠিন করে তোলে, অন্যদিকে 30% এর উপরের মান লাইন সংঘর্ষ প্রতিরোধের জন্য line-height-এ বাধ্যতামূলক বৃদ্ধির প্রয়োজন হয়।

Descender-এর ডিজিটাল মেট্রিক: OpenType এবং TrueType

ডিজিটাল ফন্টে, descender মেট্রিক টেবিলে ঋণাত্মক মান হিসাবে সংরক্ষিত থাকে। OpenType ফরম্যাটে, এটি hhea.descent ফিল্ড (hhea টেবিল) এবং sTypoDescender (OS/2 টেবিল)। উভয় মানই ঋণাত্মক কারণ এগুলি baseline থেকে নিচের দিকে মাপা হয়। TrueType-এর জন্য, OS/2 টেবিল usWinDescent ফিল্ড সহ ব্যবহৃত হয় — এর মান ধনাত্মক কিন্তু একই মেট্রিক নির্দেশ করে।

python
# fontTools এর মাধ্যমে ফন্ট থেকে descender পড়া
from fontTools.ttLib import TTFont

font = TTFont('Roboto-Regular.ttf')
hhea = font['hhea']
os2 = font['OS/2']

descent_hhea = hhea.descent        # -500 FUnits (Roboto)
typo_descender = os2.sTypoDescender # -500 FUnits
win_descent = os2.usWinDescent      # 500 (positive value)

# 16pt ফন্ট সাইজের জন্য পিক্সেলে রূপান্তর করুন
px_per_em = 16
descent_px = abs(descent_hhea) * px_per_em / 1000  # 8 px

প্ল্যাটফর্মগুলির মধ্যে গুরুত্বপূর্ণ পার্থক্য: iOS রেন্ডারিংয়ের জন্য hhea.descent ব্যবহার করে, অন্যদিকে Android OS/2 থেকে sTypoDescender ব্যবহার করে। যদি এই মানগুলি ভিন্ন হয় (যা খারাপ কনফিগার করা ফন্টে ঘটে), তাহলে একই টেক্সট iOS এবং Android-এ ভিন্ন লাইন স্পেসিং সহ প্রদর্শিত হবে। 100 FUnits-এর পার্থক্য (16 pt ফন্ট সাইজে প্রায় 1.6 px) ইতিমধ্যেই দৃশ্যমানভাবে লক্ষণীয়।

Microsoft OpenType Specification v1.9 (2025) অনুসারে, সঠিক ক্রস-প্ল্যাটফর্ম রেন্ডারিংয়ের জন্য, hhea.descent এবং sTypoDescender মান 50 FUnits-এর নির্ভুলতার মধ্যে সমান হওয়া উচিত। মোবাইল অ্যাপ্লিকেশনের জন্য ফন্ট নির্বাচন করার সময়, fontTools বা অনুরূপ ইউটিলিটির মাধ্যমে এটি পরীক্ষা করা উচিত।

iOS-এ Descender: UIFont এবং Core Graphics

iOS-এ, descender মান UIFont.descender প্রপার্টির মাধ্যমে উপলব্ধ। এই প্রপার্টি একটি ঋণাত্মক সংখ্যা ফেরত দেয় যা baseline থেকে ফন্টের নিচের প্রান্ত (descender সহ) পর্যন্ত দূরত্ব নির্দেশ করে। উদাহরণস্বরূপ, 17 pt-এ SF Pro-র জন্য descender মান প্রায় -4.2 pt। পরম মান যত বড়, ফন্টের নিচের প্রসারণ তত লম্বা।

swift
// iOS-এ UIFont এর মাধ্যমে descender পাওয়া
let font = UIFont.systemFont(ofSize: 17)
let descender = font.descender     // ~ -4.2 pt SF Pro 17pt এর জন্য
let ascender = font.ascender        // ~ 16.2 pt
let lineHeight = font.lineHeight    // ~ 20.4 pt

// descender অফসেট সহ কাস্টম রেন্ডারিং
let attrString = NSAttributedString(
    string: "Sample text with letter p and y",
    attributes: [.font: font]
)

// Core Text: descender সহ বাউন্ডিং বক্স পাওয়া
let ctFont = CTFontCreateWithName(
    "SF Pro Text" as CFString, 17, nil
)
let descent = CTFontGetDescent(ctFont)  // ~4.2 pt

TextKit (NSTextStorage, NSLayoutManager) ব্যবহার করার সময়, descender স্বয়ংক্রিয়ভাবে lineFragmentPadding এবং lineFragmentRect-এ অন্তর্ভুক্ত হয়। তবে, Core Graphics (draw(in:)) এর মাধ্যমে কাস্টম রেন্ডারিং করার সময়, আপনাকে কন্টেইনারের নিচের মার্জিনে descender-এর পরম মান যোগ করে ম্যানুয়ালি কোঅর্ডিনেট সমন্বয় করতে হবে। যদি এটি না করা হয়, তাহলে descender সহ অক্ষরগুলি রেন্ডারিং সীমার বাইরে চলে যাবে এবং কেটে যাবে।

Android-এ Descender: Paint এবং Compose

Android-এ, descender মেট্রিক Paint.FontMetrics.descent এর মাধ্যমে উপলব্ধ। iOS-এর বিপরীতে, descent মান ধনাত্মক — এটি baseline থেকে টেক্সটের নিচের প্রান্ত পর্যন্ত দূরত্ব উপস্থাপন করে। FontMetrics.bottom প্রপার্টিতে শুধু descender নয়, ফন্ট ডিজাইনার দ্বারা সুপারিশকৃত অতিরিক্ত স্থান (leading)ও অন্তর্ভুক্ত। শুধুমাত্র descender-এর সঠিক হিসাবের জন্য, bottom-এর পরিবর্তে descent ব্যবহার করুন।

kotlin
// Android-এ Paint এর মাধ্যমে descender পাওয়া
val paint = Paint().apply {
    textSize = 17 * density
}

val metrics = paint.fontMetrics
val descent = metrics.descent     // ~4.5 px 17sp এর জন্য
val bottom = metrics.bottom       // ~5.0 px leading সহ

// descender অফসেট সহ কাস্টম রেন্ডারিং
val baseline = y
canvas.drawText("নমুনা: gpq", x, baseline, paint)

// descender সহ নিচের সীমা
val bottomBound = baseline + descent  // সঠিক নিচের সীমা

Jetpack Compose-এ, descender TextLayoutResult এর মাধ্যমে পাওয়া যেতে পারে। getLineBottom মেথড লাইনের নিচের প্রান্তের Y-কোঅর্ডিনেট ফেরত দেয়, যা ইতিমধ্যেই descender অন্তর্ভুক্ত করে। বিভিন্ন ফন্ট সাইজের স্ট্রিং-এর কাস্টম লেআউট করার সময় (উদাহরণস্বরূপ, ডিসকাউন্ট মূল্য এবং পূর্ণ মূল্য), descender বিবেচনায় নিয়ে baseline সারিবদ্ধকরণ নিচের প্রান্তের সারিবদ্ধকরণের চেয়ে বেশি সঠিক ফলাফল দেয়।

kotlin
// Compose: টেক্সটের নিচের সীমা পরীক্ষা করা
val text = "Text with descenders: gpq"
var layoutResult by remember { mutableStateOf<TextLayoutResult?>(null) }

Text(
    text = text,
    onTextLayout = { layoutResult = it },
    modifier = Modifier.drawBehind {
        layoutResult?.let { result ->
            val lastLine = result.lineCount - 1
            val bottom = result.getLineBottom(lastLine)
            val top = result.getLineTop(lastLine)
            // descender কন্টেইনার সীমা অতিক্রম না করে তা পরীক্ষা করুন
        }
    }
)

Google Material Design — Typography Implementation (2025) অনুসারে, নির্দিষ্ট উচ্চতার কন্টেইনারে descender কাটা প্রতিরোধ করতে, আপনাকে ফন্টের descent-এর সমান উল্লম্ব প্যাডিং যোগ করতে হবে, বর্তমান টেক্সটে descender সহ অক্ষর থাকুক বা না থাকুক। এটি নিশ্চিত করে যে টেক্সট গতিশীলভাবে প্রতিস্থাপিত হওয়ার সময় ইন্টারফেস ভাঙবে না।

মোবাইল ইন্টারফেসে Descender এবং লাইন সংঘর্ষ

লাইন সংঘর্ষ হল এমন একটি পরিস্থিতি যেখানে উপরের লাইনের একটি অক্ষরের descender শারীরিকভাবে নিচের লাইনের একটি অক্ষরের ascender-এর সাথে সংঘর্ষ করে। মোবাইল ইন্টারফেসে, এটি বিশেষভাবে বহু-লাইন শিরোনাম, পণ্য কার্ড এবং ছোট লাইন স্পেসিং সহ টেক্সট ব্লকে লক্ষণীয়। লম্বা descender এবং ছোট line-height সহ ফন্ট ব্যবহার করলে সমস্যা আরও বেড়ে যায়।

সংঘর্ষ প্রতিরোধকারী ন্যূনতম line-height সূত্র ব্যবহার করে গণনা করা যেতে পারে: line-height = ascender + descender + 2 px মার্জিন। 17 pt-এ SF Pro-র জন্য, এটি প্রায় 16.2 + 4.2 + 2 = 22.4 pt (গুণাঙ্ক ~1.32) line-height দেয়। 16 sp-এ Roboto-র জন্য, প্রায় 1.35। যদি line-height এই মানের চেয়ে কম হয়, তাহলে descender সহ অক্ষরযুক্ত টেক্সটে সংঘর্ষ নিশ্চিত।

swift
// iOS: সংঘর্ষ প্রতিরোধের জন্য ন্যূনতম line-height গণনা করুন
let font = UIFont.systemFont(ofSize: 17)
let minLineHeight = abs(font.ascender) + abs(font.descender) + 2.0

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.minimumLineHeight = minLineHeight
paragraphStyle.maximumLineHeight = minLineHeight

let attributedText = NSAttributedString(
    string: "Text with p on first line\nand y on second line",
    attributes: [
        .font: font,
        .paragraphStyle: paragraphStyle
    ]
)

আলংকারিক এবং হাতের লেখার ফন্ট নিয়ে কাজ করার সময় বিশেষ সতর্কতা অবলম্বন করা উচিত — এদের descender em আকারের 35–40% পর্যন্ত পৌঁছাতে পারে। এই ধরনের ফন্ট খুব কমই মূল টেক্সটের জন্য ব্যবহৃত হয় তবে শিরোনামে প্রয়োগ করা যেতে পারে। শিরোনামে লম্বা descender সহ একটি অক্ষরের একক উপস্থিতি পার্শ্ববর্তী ইন্টারফেস উপাদানের সাথে সংঘর্ষ ঘটাতে পারে।

Descender নিয়ে কাজ করার সময় সাধারণ ভুল

সবচেয়ে সাধারণ ভুল হল বাটন এবং টেক্সট ফিল্ডে descender কেটে যাওয়া। যখন আমরা descender বিবেচনা না করে বাটন বা টেক্সট ফিল্ডের উচ্চতা line-height-এর সমান সেট করি, তখন descender সহ অক্ষরগুলি নিচের প্রান্ত থেকে কেটে যায়। এটি বিশেষভাবে গোলাকার কোণ বিশিষ্ট সিস্টেম বাটনে লক্ষণীয়, যেখানে descender কোণের ব্যাসার্ধ সীমার বাইরে চলে যেতে পারে।

  • নির্দিষ্ট উচ্চতার বাটন — যদি বাটনের উচ্চতা ceil(line-height) এর সমান হয়, তাহলে descender সহ অক্ষর কেটে যায়। সমাধান: উপরের এবং নিচের প্যাডিংয়ের জন্য বাটনের উচ্চতা descender-এর পরম মান (17 pt সিস্টেম ফন্টের জন্য 4–5 pt) বাড়ান।
  • TextField descender বিবেচনা ছাড়া — স্ট্যান্ডার্ড UITextField এবং EditText-এ descender বিবেচনাকারী প্যাডিং থাকে, তবে কাস্টম বাস্তবায়ন প্রায়ই এটি ভুলে যায়। পরীক্ষা করুন যে কার্সার এবং টেক্সট ব্লক descender সহ অক্ষর কাটছে না।
  • এক লাইনে ফন্ট সাইজ মেশানো — যদি NSAttributedString বা SpannableString-এ বিভিন্ন ফন্ট সাইজের সেগমেন্ট থাকে, তাহলে বড় ফন্টের descender ছোট ফন্টের ascender-এর উপর ওভারল্যাপ করতে পারে। ক্ষতিপূরণের জন্য baselineOffset ব্যবহার করুন এবং ফলাফল যাচাই করুন।
  • SVG টেক্সট রেন্ডারিং — SVG বা Canvas-এ টেক্সট রেন্ডার করার সময় (বিশেষ করে web views-এ), descender স্বয়ংক্রিয়ভাবে বিবেচনা নাও হতে পারে। সর্বদা ফন্ট সাইজের 10–15% মার্জিন সহ একটি স্পষ্ট viewBox নির্দিষ্ট করুন।

Nielsen Norman Group — Mobile Typography Research (2025) অনুসারে, 41% মোবাইল অ্যাপ্লিকেশনে কমপক্ষে একটি স্ক্রিন আছে যেখানে descender সহ টেক্সট কম্পোনেন্ট সীমার বাইরে চলে যায়। এর ফলে পঠনযোগ্যতা 15% হ্রাস পায় এবং ব্যবহারকারীর কাজ সম্পাদনের সময় বৃদ্ধি পায়। descender সহ অক্ষরযুক্ত টেক্সট দিয়ে নিয়মিত পরীক্ষা উন্নয়নের প্রাথমিক পর্যায়ে এই ধরনের সমস্যা চিহ্নিত করতে সাহায্য করে।

প্রায়শই জিজ্ঞাসিত প্রশ্ন

Descender baseline থেকে কীভাবে আলাদা?

Baseline হল অনুভূমিক রেখা যার উপর অক্ষরগুলি অবস্থান করে, অন্যদিকে descender হল এই রেখার নিচে অবস্থিত অক্ষরের অংশ। Baseline লাইনের জন্য ধ্রুবক, descender একটি নির্দিষ্ট অক্ষরের বৈশিষ্ট্য। এই ধারণাগুলি গুলিয়ে ফেলবেন না: baseline সারিবদ্ধকরণের জন্য ব্যবহৃত হয়, অন্যদিকে descender লাইন স্পেসিংকে প্রভাবিত করে এবং কন্টেইনারের উচ্চতা নির্ধারণ করার সময় বিবেচনার প্রয়োজন হয়।

Android-এ ফন্টের descender কীভাবে জানবেন?

View সিস্টেমের জন্য Paint.getFontMetrics().descent বা Jetpack Compose-এ TextLayoutResult ব্যবহার করুন। iOS-এর বিপরীতে, Android-এ descent মান ধনাত্মক এবং baseline থেকে গ্লিফের নিচের প্রান্ত পর্যন্ত দূরত্ব নির্দেশ করে। লাইনের পূর্ণ নিচের সীমা গণনা করতে, baseline-এর Y-কোঅর্ডিনেটে descent যোগ করুন।

একই ফন্টের descender iOS এবং Android-এ ভিন্ন কেন?

প্ল্যাটফর্মগুলি ফন্ট ফাইল থেকে ভিন্ন মেট্রিক টেবিল ব্যবহার করে: iOS hhea.descent ব্যবহার করে, Android os/2.sTypoDescender ব্যবহার করে। যদি ফন্টে এই মানগুলি ভিন্ন হয়, তাহলে রেন্ডারিং ভিন্ন হবে। fontTools-এর মাধ্যমে সর্বদা উভয় মান পরীক্ষা করুন। মানসম্পন্ন সিস্টেম ফন্ট (SF Pro, Roboto, Noto) উভয় প্ল্যাটফর্মের জন্য সামঞ্জস্যপূর্ণ মেট্রিক ধারণ করে।

Descender সংঘর্ষ প্রতিরোধের জন্য ন্যূনতম line-height কী প্রয়োজন?

ন্যূনতম line-height = ascender + descender + 2 px মার্জিন। iOS-এ 17 pt সিস্টেম ফন্টের জন্য এটি প্রায় 22.4 pt। Android-এ 16 sp Roboto-র জন্য — প্রায় 22 sp। নিকটতম পূর্ণসংখ্যায় রাউন্ড করার এবং descender অক্ষরের পরীক্ষা স্ট্রিং দিয়ে যাচাই করার সুপারিশ করা হয় — যদি কোনও সংঘর্ষ না থাকে, তাহলে line-height যথেষ্ট।

মোবাইল অ্যাপ্লিকেশনে খুব লম্বা descender সহ ফন্ট ব্যবহার করা যাবে কি?

হ্যাঁ, তবে কিছু শর্ত সহ। লম্বা descender সহ ফন্ট (Playfair Display, আলংকারিক টাইপফেস) শিরোনাম এবং অ্যাকসেন্ট টেক্সটের জন্য গ্রহণযোগ্য যেখানে ডিজাইনের সাথে আপস না করে line-height বাড়ানো যেতে পারে। মূল টেক্সটের জন্য, উল্লম্ব স্থান নষ্ট এড়াতে em আকারের 20–25% descender সহ ফন্ট (SF Pro, Roboto, Inter) পছন্দ করা হয়।

সারসংক্ষেপ

  • Descender — baseline-এর নিচে অবস্থিত অক্ষরের নিচের প্রসারিত উপাদান, ল্যাটিন অক্ষর “g”, “j”, “p”, “q”, “y”-তে উপস্থিত।
  • ডিজিটাল মেট্রিক — OpenType/TrueType ফরম্যাটে hhea.descent (iOS) এবং os/2.sTypoDescender (Android)।
  • iOS API — UIKit-এর জন্য UIFont.descender (ঋণাত্মক মান) এবং Core Text-এর জন্য CTFontGetDescent।
  • Android API — Paint.FontMetrics.descent (ধনাত্মক) এবং Compose-এ TextLayoutResult।
  • লাইন সংঘর্ষ — ঘটে যখন line-height < ascender + descender + 2 px মার্জিন; descender অক্ষরের পরীক্ষা স্ট্রিং দিয়ে যাচাই করা হয়।
  • কম্পোনেন্টে কাটা — বাটন, টেক্সট ফিল্ড এবং কাস্টম কন্টেইনারে descender-এর পরম মানের সমান প্যাডিং থাকা উচিত।
  • প্ল্যাটফর্ম পার্থক্য — iOS এবং Android ভিন্ন মেট্রিক টেবিল ব্যবহার করে, যার জন্য উভয় প্ল্যাটফর্মে ফন্ট পরীক্ষা করা প্রয়োজন।

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন