เรื่องของ font-size อาจดูเป็นเรื่องง่ายๆ แต่เชื่อเถอะครับ ว่ามันมีอะไรมากกว่าที่หลายๆ คนคิด บางคนอาจใช้ด้วยความเคยชิน แล้วก็ทำต่อเนื่องกันมาโดยอาจไม่รู้ว่านั่นเป็นสิ่งที่ไม่เหมาะสมนัก บางคนเขียนดีแล้ว เนื่องจากทำตามเค้า แต่อาจยังไม่เข้าใจว่าทำแบบนั้นไปเพื่ออะไร? บทความนี้ จะช่วยอธิบายเรื่องราวต่างๆ เกี่ยวกับ font-size เพื่อจะได้ใช้เป็น Guidelines ในการพัฒนาเว็บไซต์ได้อย่างเหมาะสมมากขึ้นครับ
หน่วยของ font-size มีแบบไหนบ้าง?
หน่วยของ font-size นั้น ถ้าแบ่งแบบกว้างๆ จะมี 2 แบบ ครับ คือแบบ absolute กับแบบ relative
หน่วยแบบ absolute ก็คือหน่วยที่กำหนดขนาดแบบตายตัว ไม่ขึ้นอยู่กับใครทั้งสิ้น หน่วยแบบนี้ได้แก่ px(Pixels) และ pt(Points) ครับ
- px(Pixels)มักใช้ในการแสดงผลบนหน้าจอ(Screen) โดย 1 pixel จะมีค่าเท่ากับ 1 จุดบนหน้าจอ (หน่วยที่เล็กที่สุดบนหน้าจอแสดงผล)
- pt(Points)มักใช้ในงานที่เกี่ยวกับสื่อสิ่งพิมพ์ ที่ต้องมีการ print ออกมาบนกระดาษ โดย 1 point มีค่าเท่ากับ 1/72 นิ้ว
ส่วนอีกแบบคือ หน่วยแบบ relative ครับ หน่วยแบบนี้จะตรงข้ามกับแบบ absolute เลย ตรงที่ขนาดของมันจะไม่ตายตัว แต่จะมีขนาดปรับเปลี่ยนตาม element ที่เป็น Parent ของมันครับ หน่วยที่เป็นแบบ relative ได้แก่ em(Ems) และ %(Percent)
- %(Percent)เป็นหน่วยที่ใช้สำหรับกำหนดขนาดของ property ทั่วๆ ไป สามารถใช้ได้ทั้ง width, height และอื่นๆ ซึ่งรวมไปถึง font-size
- em(Ems)อ่านว่า “เอ็ม” เป็นหน่วยสำหรับ Typography โดยเฉพาะ ซึ่ง W3C แนะนำให้ใช้หน่วยนี้ในการกำหนดขนาดของตัวอักษร
แต่ก่อนเรานิยมใช้ px
การกำหนด font-size ด้วย px เป็นที่นิยมมากในอดีต(ปัจจุบันก็ยังมีคนใช้อยู่มาก) เนื่องจากเป็นหน่วยที่มีความเชื่อถือได้ คงเส้นคงวา ไม่ว่าไปเปิดดูที่เครื่องไหน ก็แสดงผลเหมือนกันหมด(สมัยก่อนยังไม่มีหน้าจอความละเอียดสูงๆ เหมือนสมัยนี้) แต่การกำหนดขนาดด้วยวิธีนี้กลับมีข้อเสียตรงที่ มันจะทำให้ Users ไม่สามารถปรับขนาดของตัวอักษรเองได้ ตัวอย่างเช่น ในบาง web browsers หรือ screen readers จะมีฟังก์ชั่นสำหรับปรับขนาดตัวอักษร ให้เพิ่มขึ้นหรือลดลงได้(เพื่อช่วย Users ที่มีปัญหาทางสายตา) ซึ่งถ้าเรากำหนด font-size โดยใช้ px จะส่งผลให้ตัวอักษรมีขนาดเท่าเดิมตลอด ไม่เปลี่ยนไปตามขนาดที่ Users กำหนด
ทำความรู้จักกับหน่วยแบบ relative
ด้วยปัญหาดังกล่าว เราจึงไม่ควรกำหนด font-size แบบตายตัว ด้วย px ครับ แต่ควรเปลี่ยนมาใช้หน่วยแบบ relative แทน ซึ่งจะทำให้ปัญหาดังกล่าวหมดไป โดยหน่วยที่นิยมใช้ก็คือ em นั่นเองครับ เนื่องจากเป็นหน่วยสำหรับ Typography โดยเฉพาะ ต่างกับหน่วย %(Percent) ที่เป็นหน่วยกลางๆ ใช้ได้กับหลายๆ property คำถามคือ ทำไมหน่วยแบบ relative ถึงไม่มีปัญหา มันมีหลักการอย่างไร?
ก่อนอื่นต้องรู้ก่อนครับว่า ในแต่ละ web browsers จะมีการกำหนดค่าเริ่มต้นของขนาดตัวอักษรเอาไว้ โดยส่วนใหญ่แล้ว ตัวอักษรจะมีขนาดเท่ากับ 16px ซึ่งหมายความว่า ถ้าเราไม่ได้ไปกำหนด font-size ไว้ที่ elements ใดๆ เลย มันจะใช้ค่านี้ในการแสดงผลตัวอักษรออกมาครับ
หน่วยแบบ relative จะต่างจากหน่วยแบบ absolute ตรงที่ หน่วยแบบนี้จะกำหนดให้ขนาดของตัวอักษรของ element นั้นๆ มีขนาดเป็นจำนวนเท่าของขนาดตัวอักษรของ element ที่เป็น parent ของมันครับ ซึ่ง parent ระดับสูงที่สุด ไม่ใช่ใครที่ไหนครับ มันก็คือค่าเริ่มต้นของแต่ละ web browsers ที่ผมเพิ่งบอกไปนั่นเอง โดย 1em จะเท่ากับ 100% หรือคิดเป็น 1เท่า ของค่าเริ่มต้นซึ่งก็คือ 16px ครับ ถ้าเรากำหนดไว้ 2em หรือ 200% ก็จะได้เป็น 32px เพื่อให้เข้าใจได้ง่ายขึ้น ลองมาดูตัวอย่างกันดีกว่าครับ
1
2
3
4
5
6
7
8
9
10
11
12
|
article {
font-size:0.875em; /* 16x0.875=14px */
}
article h1 {
font-size:1.714em; /* 14x1.714=24px */
}
article p {
font-size:1em; /* 14x1=14px */
}
article footer {
font-size:0.857em; /* 14x0.857=12px */
}
|
จากตัวอย่างนี้ ผมกำหนดให้ article มีขนาดตัวอักษรเป็น 0.875em จำได้มั้ยครับว่า 1em = 100% = 16px ก็จะได้ว่า 0.875em จะมีค่าเท่ากับ 87.5% หรือ 16×0.875 ซึ่งก็คือ 14px นั่นเอง
แต่เมื่อดูที่ h1 ที่อยู่ภายใน article จะพบว่าผมเอา 1.714 ไปคูณกับ 14px แทนที่จะเป็น 16px ที่เป็นเช่นนี้เพราะว่า หน่วยแบบ relative จะเทียบกับ Parent ที่อยู่ใกล้ชิดกับมันมากที่สุดครับ ในที่นี้ article ที่มี font-size ขนาด 14px เป็น parent ที่อยู่ใกล้ชิดกับ h1 มากกว่าค่าเริ่มต้นของ web browser ที่มีค่าเป็น 16px ดังนั้น ค่า 14px จึงถูกนำมาใช้แทนครับ
จะเห็นว่าหน่วยแบบ relative มีข้อดีตรงการจัดการกับขนาดของตัวอักษรของ elements ที่ซ้อนๆ กันครับ หากเราพบว่าขนาดตัวอักษรของ article เล็กไปหน่อย ให้เราปรับ font-size ที่ article ที่เดียว มันก็จะส่งผลไปถึง elements ต่างๆ ที่เป็น children ของมันทั้งหมดครับ ตรงข้ามกับหน่วยแบบ absolute อย่าง px ที่เราต้องไปไล่แก้ css rules ของ elements ต่างๆ จนครบทั้งหมด
ด้วยเหตุนี้เองครับ ทำให้การกำหนด font-size แบบ em ไม่มีปัญหากับฟังก์ชั่นปรับขนาดตัวอักษร เนื่องจากฟังก์ชั่นพวกนี้ เป็นเหมือนการปรับค่าเริ่มต้นของขนาดตัวอักษรของ web browser ให้เพิ่มขึ้น หรือลดลง ซึ่งก็คือการทำให้ตัวคูณของเราเปลี่ยนจากค่าเดิมที่เป็น 16px นั่นเองครับ
อย่างไรก็ตาม ยังคงพบปัญหาเกี่ยวกับการกำหนด font-size ด้วย em อยู่บ้าง ใน IE6 และ IE7 ซึ่งพบว่าเมื่อ Users ปรับขนาด Text Size จากปกติที่เป็น Medium เป็นค่าอื่น ตัวอักษรแม้จะปรับขนาดตามได้ก็จริง แต่กลับมีขนาดเล็กเกินไป หรือใหญ่เกินไป จนไม่เหมาะแก่การอ่านครับ ปัญหานี้ เราสามารถแก้ได้ง่ายๆ โดยการกำหนด font-size ที่ body โดยใช้หน่วยเป็น % ครับ วิธีนี้จะช่วยให้ฟังก์ชั่นปรับขนาดตัวอักษรของ web browsers หรือ screen readers ต่างๆ ทำงานได้ไม่ผิดเพี้ยน เหมาะแก่การอ่านมากขึ้นครับ
แล้ว em กับ % แตกต่างกันอย่างไร?
คำถามนี้ ถือเป็นคำถามยอดฮิตเลยครับ อย่างที่ผมได้บอกไปแล้วว่า การกำหนด font-size ที่ body ให้กำหนดด้วย % แทนที่จะเป็น em เนื่องจากจะทำให้แสดงผลได้อย่างสมเหตุสมผล ไม่ผิดเพี้ยนในบาง web browsers แต่จริงๆ แล้ว em กับ % มีความต่างกันมากกว่านั้น
ทั้ง em และ % ต่างก็เป็นหน่วยแบบ relative ครับ ประเด็นมันอยู่ที่ ขนาดของ 2 หน่วยนี้ มันสัมพันธ์กับอะไร? หน่วย em ไม่ว่าเราจะใช้กับ property อะไรก็ตาม(font-size, line-height, width, height, margin, padding) ขนาดของมันจะขึ้นอยู่กับ font-size ของ parent เสมอ ในขณะที่ หน่วยแบบ % หากใช้กับ property อะไร จะมีขนาดเทียบกับ property นั้นๆ ของ parent ครับ
เพื่อให้เห็นภาพ สมมติเราทำเว็บไซต์ 2 คอลัมน์ ถ้าเรากำหนดความกว้างของแต่ละคอลัมน์ด้วย % เช่น 30% และ 70% ตามลำดับ เวลาเราปรับ Text Size ของ web browser ให้ใหญ่ขึ้น เราจะพบว่าขนาดของตัวอักษรเพิ่มขึ้น ในขณะที่ความกว้างของคอลัมน์ยังคงเท่าเดิม
ในทางกลับกัน ถ้าเรากำหนดความกว้างของแต่ละคอลัมน์ด้วย em เช่น 18.75em และ 43.75em ตามลำดับ เวลาเราปรับ Text Size ของ web browser ให้ใหญ่ขึ้น เราจะพบว่าขนาดของตัวอักษรเพิ่มขึ้น พร้อมๆ กับความกว้างของคอลัมน์ที่เพิ่มขึ้นตามไปด้วย ซึ่งถ้าปรับ Text Size ให้เพิ่มขึ้นมากๆ อาจทำให้เกิด scrollbar ในแนวนอนได้
นี่ล่ะครับ ความแตกต่างระหว่าง em กับ % ผมบอกไปแล้วว่า em เกิดมาเพื่อ Typography ซึ่งหมายความว่า ไม่ว่าเราจะใช้มันกับ property ใดก็ตาม มันจะเทียบกับ font-size เสมอ ด้วยเหตุนี้เอง หน่วย em จึงเหมาะมากในการใช้กับ line-height, margin และ padding เนื่องจากมันจะสามารถปรับให้เข้ากับ Text Size ที่เปลี่ยนไปได้อย่างลงตัว
Trick 62.5%
บางคนอาจบ่นว่า em ใช้งานยากจัง แม้ 1em จะมีขนาดเท่ากับ 16px แต่ในการใช้งานจริง ตัวอักษรขนาด 16px อาจดูใหญ่เกินไป สมมติอยากได้ตัวอักษรขนาด 14px ก็ต้องคำนวณโดยการเอา 14ตั้ง แล้วหารด้วย 16 ซึ่งจะได้เท่ากับ 0.875em หรือ 87.5% นั่นเอง ยังงี้จะเขียนเว็บไซต์ทั้งที อาจต้องกดเครื่องคิดเลขไปด้วย ลำบากไปมั้ย?
สำหรับคนที่ไม่อยากคำนวณอะไรมากมาย มีวิธีแก้ง่ายๆ โดยการกำหนด font-size ที่ body ให้เป็น 62.5% ครับ ลองเอา 16×0.625 ดูครับ จะได้ค่าเท่ากับ 10px พอดี ซึ่งก็หมายความว่า เราได้กำหนด base font-size ให้เป็น 10px แล้ว ทีนี้ elements ใดๆ ก็ตาม ที่มี body เป็น parent โดยตรง จะได้ว่า 1em มีค่าเท่ากับ 10px ครับ ต่อไปนี้ ถ้าเราอยากได้ font-size ขนาดไหน เราก็สามารถกำหนดให้อยู่ในรูปแบบ em ได้อย่างง่ายดาย เช่น อยากได้ขนาด 14px ก็ให้ใส่ 1.4em อยากได้ 24px ก็ให้ใส่ 2.4em เป็นต้น
ความซ้ำซ้อนของหน่วยแบบ relative
แต่อย่าลืมนะครับ ว่าหน่วย em เป็นหน่วยแบบ relative ซึ่งมันจะมีขนาดเป็นเท่าของ parent ของมัน ไม่ได้มีขนาดเป็นเท่าของ “body” ดังนั้น หากเราคิดจะใช้ Trick 62.5% เราต้องรู้ด้วยว่า font-size ที่เราได้กำหนดให้กับ elements ต่างๆ มันจะส่งผลไปถึง elements ที่เป็น children ของมันทั้งหมดด้วย ลองมาดูตัวอย่างดีกว่าครับ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
body {
font-size:62.5%; /* set base font-size เป็น 10px */
}
article {
font-size:1.6em; /* อยากได้ 16px แสดงผล 16px ได้ถูกต้อง (10x1.6=16) */
}
article h1 {
font-size:2.4em; /* อยากได้ 24px แต่กลับแสดงผล 38.4px (16x2.4=38.4) */
}
article p {
font-size:1.6em; /* อยากได้ 16px แต่กลับแสดงผล 25.6px (16x1.6=25.6) */
}
article footer {
font-size:1.4em; /* อยากได้ 14px แต่กลับแสดงผล 22.4px (16x1.4=22.4) */
}
|
จากตัวอย่างด้านบน จะพบว่า rules 3 อันล่างสุด แสดงผลไม่ตรงตามที่เราหวังไว้ ที่เป็นเช่นนี้ เพราะว่ามันไปเทียบ font-size กับ article ซึ่งมีค่าเป็น 16px แทนที่จะไปเทียบกับ body ที่เราได้กำหนดไว้ที่ 10px
วิธีแก้ปัญหานี้คือ หากเราจะกำหนด font-size ที่จุดไหน ให้เรากำหนดไปที่ตัว element นั้นๆ โดยตรงเลยครับ อย่าไปกำหนดที่ตัว parent เพราะจะทำให้ elements ที่เป็น children ไม่ได้รับประโยชน์จาก Trick 62.5% อีกต่อไป
บางคนยังบ่นต่อว่า ถ้าคิดจะใช้ Trick 62.5% ยังงี้การเขียน css rules ก็ต้องระมัดระวังมากเป็นพิเศษน่ะสิ เรามีทางแก้ครับ ใน CSS3 มีหน่วยของ font-size แบบใหม่ที่เรียกว่า rem(Root Em) เพิ่มเข้ามา โดยหน่วย rem นี้ มีคุณสมบัติเหมือนกับหน่วย em แทบทุกประการ เพียงแต่ rem จะเทียบขนาดกับ root element ซึ่งก็คือ html เสมอครับ ดังนั้น หากเราคิดจะใช้ rem ให้เรากำหนด font-size ที่ html ให้เป็น 62.5% แทน ทีนี้ ไม่ว่า elements ใดก็ตามที่ใช้หน่วย rem จะได้ผลของ Trick 62.5% เสมอครับ
คำถามต่อมาคือ rem ใช้ได้กับ web browsers ไหนบ้าง? หากเข้าไปดูที่
Compatibility table for support of rem units จะพบว่าเราสามารถใช้ rem ได้ตั้งแต่ IE9 ขึ้นไป แล้ว IE เวอร์ชั่นที่ต่ำกว่านั้นล่ะ? ให้เราแก้ปัญหาโดยการกำหนด fall-back สำหรับ web browsers ที่ไม่รองรับ rem ครับ โดยการกำหนด font-size ด้วย px แทน ตามตัวอย่างต่อไปนี้
|
html {
font-size: 62.5%; /* set root font-size เป็น 10px */
}
body {
font-size: 14px; /* กรณีไม่รองรับ rem */
font-size: 1.4rem; /* กรณีรองรับ rem */
}
h1 {
font-size: 24px; /* กรณีไม่รองรับ rem */
font-size: 2.4rem; /* กรณีรองรับ rem */
}
|
แก้ปัญหาที่ต้นเหตุ
มาถึงตรงจุดนี้ บางคนอาจมองว่า Trick 62.5% นั้นช่างสุดยอดเหลือเกิน สามารถแก้ปัญหาเกี่ยวกับการปรับ Text Size ได้ แถมยังทำให้การกำหนดขนาดแบบ em ทำได้ง่ายขึ้นอีกด้วย แต่อย่าลืมว่า Trick นี้ ต้องแลกกับความยากลำบากในการแก้ปัญหาที่ตามมา ไม่ว่าจะเป็นปัญหาการส่งผลซ้ำซ้อนกันของหน่วยแบบ relative รวมไปถึงปัญหาที่บาง web browsers ยังไม่รองรับหน่วย rem
นอกจากนี้ การกำหนด base font-size เป็น 10px ซึ่งถือเป็นขนาดตัวอักษรที่เล็กมาก ทำให้เราต้องมาเขียน css rules มากขึ้น เพื่อปรับให้เป็นขนาดที่เราต้องการจริงๆ และหากเราเลือกใช้ Trick 62.5% นี้ ก็เท่ากับว่าเราถูกบีบให้เขียนเทียบกับ base font-size ที่ 10px ไปตลอด นั่นหมายความว่า เราไม่ได้ใช้ประโยชน์จากหน่วยแบบ relative เท่าที่ควร ตัวอย่างเช่น หากเราต้องการปรับขนาดของตัวอักษรภายในกล่อง “บทความล่าสุด” ให้ใหญ่ขึ้นสัก 20% ถ้าเราไม่ได้ใช้ Trick 62.5% สิ่งที่เราต้องทำก็แค่ไปเขียน css rule ที่ container ของ “บทความล่าสุด” จากเดิมเป็นเท่าไร(สมมติ 1em) ก็ให้เราบวกไปอีก 20%(จะได้ 1.2em) ก็เรียบร้อยแล้ว ซึ่งจะส่งผลให้ขนาดตัวอักษรภายในกล่องนี้ เพิ่มขึ้นด้วยสัดส่วนเดิมทั้งกล่อง ในทางกลับกัน ถ้าเราใช้ Trick 62.5% เราจะต้องไล่ปรับ css rules ของ elements ที่อยู่ภายในกล่อง “บทความล่าสุด” ทั้งหมด
กำหนด base font-size ให้ตรงกับความต้องการมากที่สุด
ถ้าพิจารณาดีๆ จะพบว่าปัญหาทั้งหมดนี้ เกิดจากการที่เราไปฝืนธรรมชาติครับ การใช้ Trick 62.5% ทำให้การกำหนด font-size ด้วย em ง่ายขึ้นก็จริง แต่ต้องแลกกับ base font-size ขนาด 10px ซึ่งไม่ใช่ขนาดที่เราต้องการจะใช้จริงๆ ด้วยเหตุนี้เอง ทำให้เกิดปัญหาต่างๆ ตามมามากมาย
การกำหนด base font-size ให้เป็นค่าที่เราต้องการจะใช้จริงๆ กลับเป็นทางเลือกที่ดูจะเหมาะสมกว่าครับ ให้เราดู content ของเรา ว่าส่วนใหญ่ควรมีขนาดตัวอักษรเป็นเท่าไร แล้วกำหนดไว้ที่ body เลยครับ หากต้องการ 16px ก็ให้กำหนดเป็น 100% แต่ถ้าต้องการสัก 13px ก็ให้กำหนดเป็น 81.25% ทีนี้ ส่วนไหนที่มีขนาดตรงกับ base font-size เราก็ไม่จำเป็นต้องไปเขียน css rule แล้วครับ เราจะเขียนแค่ส่วนที่มีขนาดมากกว่า หรือน้อยกว่าเท่านั้น เช่น h1 หรือ footer เป็นต้น
จริงๆ แล้ว การกำหนด font-size แบบ em ไม่ได้ยากเย็นอะไรมากมายครับ เนื่องจาก web browsers จะแสดงผลเฉพาะขนาดตัวอักษรที่เป็นจำนวนเต็มเท่านั้น หากเรากำหนดขนาดที่ไม่เป็นจำนวนเต็ม มันจะปัดให้เราเองครับ สมมติเราต้องการให้แสดงตัวอักษรขนาด 13px ถ้าคิดเป็น em ก็ให้เอา 13/16 จะได้ 0.8125 หรือ 0.813em นั่นเอง ซึ่งเราสามารถใส่แค่ 0.8em ก็ได้ครับ เพราะ 0.8em จะเท่ากับ 16×0.8 หรือ 12.8px ซึ่งอย่างที่ได้บอกไปแล้ว web browsers จะแสดงผลเป็น 13px ครับ
1em ไม่ได้เท่ากับ 16px
ถ้าใครตั้งใจอ่านบทความนี้ และพยายามทำความเข้าใจตามมาโดยตลอด จะเห็นว่าจริงๆ แล้ว 1em ไม่ได้มีค่าเท่ากับ 16px เลยครับ 1em ก็มีค่าเท่ากับ 1em หรือ 1เท่าของขนาดตัวอักษร ไม่มีความหมายอื่น ที่ผมบอกอย่างนี้เพราะว่าในแต่ละ web browsers นั้นมีการตั้งค่าขนาดตัวอักษรที่ต่างกันออกไป ซึ่งมันจะกำหนดมาให้เป็นค่าที่เหมาะสมกับอุปกรณ์นั้นๆ มากที่สุดอยู่แล้ว นั่นหมายความว่าค่านี้ไม่จำเป็นต้องเป็น 16px เสมอไป ด้วยเหตุนี้เอง เราจึงไม่ควรพยายามที่จะแปลงหน่วย em ให้เป็นหน่วย px หรือหน่วยใดๆ แต่ให้เราดูว่า 1em นั้น มีขนาดพอดีกับที่เราต้องการมั้ย? ถ้าใหญ่ไปก็ลองลดลงมาเป็น 0.9 em เล็กไปก็ให้ลองเพิ่มเป็น 1.1em ทำแบบนี้จนกว่าจะได้ขนาดตัวอักษรที่พอใจเท่านั้นเองครับ