ตัวอักษรแบบตอบสนองและธีมขององค์ประกอบ
ปรับขนาดข้อความและปรับแต่งธีมองค์ประกอบเพื่อสร้างแบรนด์ที่สอดคล้องกันในทุกอุปกรณ์
ตัวอักษรแบบตอบสนองและธีมขององค์ประกอบ เป็นบทเรียน Flutter Mobile Development ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Flutter Mobile Development และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Flutter Mobile Development มีบทเรียนทั้งหมด 4 บทเรียน
บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ
Why Typography Scales
A design system keeps your app's look consistent across phones, foldables, and tablets. Two pillars hold it together: typography (how text looks at every size) and component theming (how buttons, cards, and inputs are styled once and reused everywhere).
In Material 3, both live inside ThemeData. Instead of styling each widget by hand, you define the rules centrally and let widgets inherit them. This lesson shows how to scale text responsively and customize component themes for consistent cross-device branding.
- TextTheme carries the type scale (display, headline, title, body, label).
- Component themes (e.g.
ElevatedButtonThemeData) shape each widget family.
The Material 3 Type Scale
Material 3 defines a type scale of 15 named styles grouped into 5 roles. Each role has Large, Medium, and Small variants:
displayLarge/Medium/Small— big, expressive hero text.headlineLarge/Medium/Small— section headers.titleLarge/Medium/Small— list and dialog titles.bodyLarge/Medium/Small— paragraphs and main content.labelLarge/Medium/Small— buttons, captions, chips.
You read these from context anywhere in your widget tree, so a heading always matches the same scale no matter where it appears.
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Welcome', style: textTheme.displaySmall),
Text('Your daily summary', style: textTheme.titleMedium),
Text('Here is what happened today.', style: textTheme.bodyMedium),
],
);
}Customizing the TextTheme
To brand your typography, override the textTheme on ThemeData. A clean approach is to start from a base text theme and copyWith only the styles you want to change. This keeps the rest of the Material defaults intact.
Notice how each style is a TextStyle with explicit fontSize, fontWeight, and letterSpacing. Defining them in one place guarantees consistency across every screen.
final ThemeData appTheme = ThemeData(
useMaterial3: true,
textTheme: const TextTheme(
displaySmall: TextStyle(
fontSize: 36,
fontWeight: FontWeight.w700,
letterSpacing: -0.5,
),
titleMedium: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
bodyMedium: TextStyle(
fontSize: 14,
height: 1.4,
),
),
);Responsive Sizing with MediaQuery
Hard-coded font sizes look great on one device but cramped or oversized on another. Use MediaQuery to read the screen width and pick a scale factor. A common pattern: clamp a base size between a minimum and a maximum so text never gets absurdly small or large.
Here we compute a responsive headline size from the available width, then apply it on top of the theme's style with copyWith.
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width;
// Scale headline between 24 and 40 based on width.
final headlineSize = (width / 14).clamp(24.0, 40.0);
final base = Theme.of(context).textTheme.headlineMedium;
return Text(
'Cross-device branding',
style: base?.copyWith(fontSize: headlineSize),
);
}Respecting the User's Text Scale
Accessibility matters: users can enlarge system text. In modern Flutter, read this via MediaQuery.textScalerOf(context), which returns a TextScaler. Avoid disabling it outright; instead clamp it so very large settings don't break your layout while still honoring the user's preference.
Wrap a subtree in MediaQuery with a clamped scaler to bound the growth.
Widget build(BuildContext context) {
final scaler = MediaQuery.textScalerOf(context)
.clamp(minScaleFactor: 1.0, maxScaleFactor: 1.6);
return MediaQuery(
data: MediaQuery.of(context).copyWith(textScaler: scaler),
child: const Text('Readable yet bounded'),
);
}A Pure-Dart Responsive Helper
The scaling logic itself is plain Dart and easy to unit-test in isolation, no Flutter needed. Below is a small function that maps a screen width to a font size with a linear ramp between two breakpoints, then clamps the result. Testing this pure logic separately keeps your widgets thin.
double responsiveFontSize(
double width, {
double minWidth = 320,
double maxWidth = 840,
double minSize = 14,
double maxSize = 22,
}) {
if (width <= minWidth) return minSize;
if (width >= maxWidth) return maxSize;
final t = (width - minWidth) / (maxWidth - minWidth);
return minSize + t * (maxSize - minSize);
}
void main() {
print(responsiveFontSize(300)); // 14.0 (clamped)
print(responsiveFontSize(580)); // ~17.0
print(responsiveFontSize(900)); // 22.0 (clamped)
}Introducing Component Themes
Beyond text, Material 3 lets you theme entire widget families centrally. Each has a dedicated *ThemeData slot on ThemeData:
elevatedButtonTheme,filledButtonTheme,textButtonThemecardTheme,chipTheme,appBarThemeinputDecorationThemefor text fields
Set them once and every matching widget inherits the styling. This is the heart of a design system: change the brand in one file, see it everywhere.
Theming Elevated Buttons
Use ElevatedButtonThemeData with a ButtonStyle to standardize padding, shape, and text style for every ElevatedButton in the app. Tying the button's label style back to labelLarge keeps it aligned with your type scale.
Because the theme supplies these defaults, individual buttons stay clean: ElevatedButton(onPressed: ..., child: Text('Save')) with no inline styling.
final elevatedButtonTheme = ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
textStyle: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
),
),
);Theming Cards and Inputs
Cards and text fields are everywhere in mobile UIs, so theming them pays off fast. CardThemeData controls elevation, shape, and margin; InputDecorationTheme standardizes borders, fills, and label behavior for every TextField.
With these in place, a form looks consistent across the app without repeating decoration code on each field.
final cardTheme = CardThemeData(
elevation: 1,
margin: const EdgeInsets.all(8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
);
final inputDecorationTheme = InputDecorationTheme(
filled: true,
contentPadding: const EdgeInsets.all(16),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none,
),
);Assembling the Full ThemeData
Now combine typography and component themes into a single ThemeData. Pairing it with a ColorScheme.fromSeed gives you a coherent Material 3 palette. Pass this theme to MaterialApp(theme: ...) and the whole app picks it up.
This one object is your design system's source of truth: brand colors, type scale, and component styling, all together.
ThemeData buildBrandTheme() {
return ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF6750A4)),
textTheme: const TextTheme(
titleMedium: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
bodyMedium: TextStyle(fontSize: 14, height: 1.4),
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
),
cardTheme: CardThemeData(
elevation: 1,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
);
}Reading the Theme in Widgets
Once the theme is set, widgets should pull styling from it rather than hard-coding values. Use Theme.of(context) to access the textTheme, colorScheme, and any component theme.
This makes your widgets theme-agnostic: switch to a dark theme or rebrand, and they update automatically because they never assumed a specific color or size.
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Account', style: theme.textTheme.titleMedium),
const SizedBox(height: 8),
Text(
'Manage your profile and settings.',
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
],
),
),
);
}Quick Check
You want every TextField in your app to share the same rounded, filled border without repeating decoration code on each field. Which approach fits a Material 3 design system best?
Recap
You built the typography and component foundation of a Material 3 design system:
- Type scale: the 15 named styles (display, headline, title, body, label) read via
Theme.of(context).textTheme. - Custom TextTheme: override fonts and sizes centrally with
copyWith. - Responsive sizing: derive sizes from
MediaQuerywidth andclampthem, and respect (but bound) the user'stextScalerfor accessibility. - Component themes:
ElevatedButtonThemeData,CardThemeData, andInputDecorationThemestyle entire widget families once. - Single source of truth: assemble everything into one
ThemeDatawithColorScheme.fromSeed, then read it in theme-agnostic widgets.
The result is consistent cross-device branding that adapts to screen size and user preferences without per-widget styling.
เรียนรู้ Dart ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 22
- บทเรียน
- 88
คำถามที่พบบ่อย
บทเรียน “ตัวอักษรแบบตอบสนองและธีมขององค์ประกอบ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ตัวอักษรแบบตอบสนองและธีมขององค์ประกอบ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Flutter Mobile Development ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Flutter Mobile Development มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ตัวอักษรแบบตอบสนองและธีมขององค์ประกอบ”
ปรับขนาดข้อความและปรับแต่งธีมองค์ประกอบเพื่อสร้างแบรนด์ที่สอดคล้องกันในทุกอุปกรณ์ คุณปฏิบัติ Flutter Mobile Development ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Flutter Mobile Development หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Flutter Mobile Development บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “ตัวอักษรแบบตอบสนองและธีมขององค์ประกอบ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Flutter Mobile Development นี้ได้ไหม
ได้ บทเรียน Flutter Mobile Development ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ชุดสี Material 3 และสีตั้งต้น
- สีแบบไดนามิกและธีมสว่าง/มืดแบบปรับตามบริบท
- ThemeExtension แบบกำหนดเองสำหรับโทเค็นแบรนด์
- ตัวอักษรแบบตอบสนองและธีมขององค์ประกอบ