ปัญหา CSS ทั่วไปสำหรับโครงการส่วนหน้า

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ การแสดงผลและการโต้ตอบมีความสอดคล้องกันมากขึ้นในเบราว์เซอร์ต่างๆ ในช่วงไม่กี่ปีที่ผ่านมา มันยังไม่สม่ำเสมออย่างสมบูรณ์ และปัญหาเล็ก ๆ มากมายอาจทำให้คุณสะดุด นอกเหนือจากปัญหาเหล่านี้แล้ว ยังมีตัวแปรของขนาดหน้าจอที่แตกต่างกัน การตั้งค่าภาษา และข้อผิดพลาดของมนุษย์ทั่วไป และเราพบสิ่งเล็กๆ มากมายที่จะทำให้นักพัฒนาต้องสะดุดล้ม

เมื่อใช้อินเทอร์เฟซผู้ใช้ในเบราว์เซอร์ คุณควรลดความแตกต่างและปัญหาเหล่านั้นให้เหลือน้อยที่สุดในทุกที่ที่ทำได้ เพื่อให้ UI คาดเดาได้ การติดตามความแตกต่างทั้งหมดนั้นเป็นเรื่องยาก ดังนั้นฉันจึงได้รวบรวมรายการปัญหาทั่วไปพร้อมวิธีแก้ไข เพื่อเป็นคู่มืออ้างอิงที่สะดวกสำหรับเมื่อคุณกำลังทำงานในโครงการใหม่

เอาล่ะ.

1. รีเซ็ตพื้นหลังของ button และองค์ประกอบ input

เมื่อเพิ่มปุ่ม ให้รีเซ็ตพื้นหลัง มิฉะนั้นปุ่มจะดูแตกต่างออกไปในเบราว์เซอร์ต่างๆ ในตัวอย่างด้านล่าง ปุ่มเดียวกันจะแสดงใน Chrome และ Safari หลังเพิ่มพื้นหลังสีเทาเริ่มต้น

(ตัวอย่างขนาดใหญ่)

การรีเซ็ตพื้นหลังจะช่วยแก้ปัญหานี้ได้:

 button { appearance: none; background: transparent; /* Other styles */ } 

ดูปุ่มปากกาและอินพุตโดย Ahmad Shadeed (@shadeed) บน CodePen

ดูปุ่มปากกาและอินพุตโดย Ahmad Shadeed (@shadeed) บน CodePen
เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

2. ล้น: scroll เทียบกับ auto

หากต้องการจำกัดความสูงขององค์ประกอบและอนุญาตให้ผู้ใช้เลื่อนภายในได้ ให้เพิ่ม overflow: scroll-y ซึ่งจะดูดีใน Chrome บน macOS อย่างไรก็ตาม ใน Chrome Windows แถบเลื่อนจะอยู่ที่นั่นเสมอ (แม้ว่าเนื้อหาจะสั้น) เนื่องจาก scroll-y จะแสดงแถบเลื่อนโดยไม่คำนึงถึงเนื้อหา ในขณะที่ overflow: auto จะแสดงแถบเลื่อนเมื่อจำเป็นเท่านั้น

ซ้าย: Chrome บน macOS ขวา: Chrome บน Windows (ตัวอย่างขนาดใหญ่)
 .element { height: 300px; overflow-y: auto; } 

ดู Pen overflow-y โดย Ahmad Shadeed (@shadeed) บน CodePen

ดู Pen overflow-y โดย Ahmad Shadeed (@shadeed) บน CodePen

3. เพิ่ม flex-wrap

ทำให้องค์ประกอบทำงานเป็นคอนเทนเนอร์แบบยืดหยุ่นโดยการเพิ่ม display: flex อย่างไรก็ตาม เมื่อขนาดหน้าจอเล็กลง เบราว์เซอร์จะแสดงแถบเลื่อนแนวนอนในกรณีที่ไม่ได้เพิ่ม flex-wrap

 <div class="wrapper"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div>
 .wrapper { display: flex; } .item { flex: 0 0 120px; height: 100px; }

ตัวอย่างข้างต้นจะใช้งานได้ดีบนหน้าจอขนาดใหญ่ บนมือถือ เบราว์เซอร์จะแสดงแถบเลื่อนแนวนอน

ซ้าย: แถบเลื่อนแนวนอนจะแสดงขึ้น และรายการจะไม่ถูกห่อ ขวา: รายการถูกห่อเป็นสองแถว (ตัวอย่างขนาดใหญ่)

การแก้ปัญหาค่อนข้างง่าย ผู้ห่อควรรู้ว่าเมื่อไม่มีที่ว่างก็ควรห่อสิ่งของ

 .wrapper { display: flex; flex-wrap: wrap; } 

ดู Pen flex-wrap โดย Ahmad Shadeed (@shadeed) บน CodePen

ดู Pen flex-wrap โดย Ahmad Shadeed (@shadeed) บน CodePen

4. อย่าใช้ justify-content: space-between เมื่อจำนวน Flex Items เป็นไดนามิก

เมื่อ justify-content: space-between กับคอนเทนเนอร์แบบยืดหยุ่น มันจะกระจายองค์ประกอบและปล่อยให้มีช่องว่างระหว่างกันในปริมาณที่เท่ากัน ตัวอย่างของเรามีการ์ดแปดรายการและดูดี เกิดอะไรขึ้นถ้าจำนวนรายการเป็นเจ็ด? องค์ประกอบแถวที่สองจะดูแตกต่างจากแถวแรก

เครื่องห่อที่มีแปดรายการ (ตัวอย่างขนาดใหญ่)
ห่อด้วยสิ่งของเจ็ดชิ้น (ตัวอย่างขนาดใหญ่)

ดู Pen justify-content โดย Ahmad Shadeed (@shadeed) บน CodePen

ดู Pen justify-content โดย Ahmad Shadeed (@shadeed) บน CodePen

ในกรณีนี้ การใช้กริด CSS จะเหมาะสมกว่า

5. คำยาวและลิงค์

เมื่อมีการดูบทความบนหน้าจอมือถือ คำยาวๆ หรือลิงก์ในบรรทัดอาจทำให้แถบเลื่อนแนวนอนปรากฏขึ้น การใช้ word-break ของ CSS จะป้องกันไม่ให้เกิดขึ้น

ตัวอย่างขนาดใหญ่
 .article-content p { word-break: break-all; } 
(ตัวอย่างขนาดใหญ่)

ตรวจสอบ CSS-Tricks สำหรับรายละเอียด

6. การไล่ระดับสีแบบโปร่งใส

เมื่อเพิ่มการไล่ระดับสีด้วยจุดเริ่มต้นและจุดสิ้นสุดที่โปร่งใส จะมีลักษณะเป็นสีดำใน Safari นั่นเป็นเพราะว่า Safari ไม่รู้จักคีย์เวิร์ดที่ transparent โดยการแทนที่ด้วย rgba(0, 0, 0, 0) มันจะทำงานตามที่คาดไว้ สังเกตภาพหน้าจอด้านล่าง:

บน: Chrome 70. ล่าง: Safari 12. (ตัวอย่างขนาดใหญ่)
 .section-hero { background: linear-gradient(transparent, #d7e0ef), #527ee0; /*Other styles*/ }

สิ่งนี้ควรเป็น:

 .section-hero { background: linear-gradient(rgba(0, 0, 0,0), #d7e0ef), #527ee0; /*Other styles*/ }

7. ความเข้าใจผิดเกี่ยวกับความแตกต่างระหว่าง auto-fit auto-fill ใน CSS Grid

ในกริด CSS ฟังก์ชัน repeat สามารถสร้างเค้าโครงคอลัมน์ที่ตอบสนองได้โดยไม่ต้องใช้คิวรี่สื่อ ในการบรรลุเป้าหมายนั้น ให้ใช้ auto-fill auto-fit อัตโนมัติ

 .wrapper { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); } 
(ตัวอย่างขนาดใหญ่)

กล่าวโดยย่อ auto-fill จะจัดเรียงคอลัมน์โดยไม่ขยายความกว้าง ในขณะที่ auto-fit จะยุบคอลัมน์ให้มีความกว้างเป็นศูนย์ แต่เฉพาะในกรณีที่คุณมีคอลัมน์ว่าง Sara Soueidan ได้เขียนบทความที่ยอดเยี่ยมในหัวข้อนี้

8. แก้ไของค์ประกอบที่ด้านบนของหน้าจอเมื่อวิวพอร์ตไม่สูงพอ

หากคุณแก้ไของค์ประกอบที่ด้านบนของหน้าจอ จะเกิดอะไรขึ้นหากวิวพอร์ตไม่สูงพอ เรียบง่าย: จะใช้พื้นที่หน้าจอ และด้วยเหตุนี้ พื้นที่แนวตั้งที่ผู้ใช้สามารถเรียกดูเว็บไซต์จะมีขนาดเล็กและไม่สบายใจ ซึ่งจะทำให้ประสบการณ์ใช้งานลดลง

 @media (min-height: 500px) { .site-header { position: sticky; top: 0; /*other styles*/ } }

ในตัวอย่างด้านบน เรากำลังบอกให้เบราว์เซอร์แก้ไขส่วนหัวให้อยู่ด้านบนสุดก็ต่อเมื่อความสูงของวิวพอร์ตเท่ากับหรือมากกว่า 500 พิกเซล

สำคัญเช่นกัน: เมื่อคุณใช้ position: sticky จะไม่ทำงานเว้นแต่คุณจะระบุคุณสมบัติ top

ตัวอย่างขนาดใหญ่

ดูข้อความค้นหาสื่อแนวตั้งของปากกา: แก้ไขส่วนหัวโดย Ahmad Shadeed (@shadeed) บน CodePen

ดูข้อความค้นหาสื่อแนวตั้งของปากกา: แก้ไขส่วนหัวโดย Ahmad Shadeed (@shadeed) บน CodePen

9. การตั้งค่า max-width สำหรับรูปภาพ

เมื่อเพิ่มรูปภาพ ให้กำหนด max-width: 100% เพื่อให้รูปภาพปรับขนาดเมื่อหน้าจอมีขนาดเล็ก มิฉะนั้น เบราว์เซอร์จะแสดงแถบเลื่อนแนวนอน

 img { max-width: 100%; }

10. การใช้ CSS Grid เพื่อกำหนดองค์ประกอบ main และส่วน aside

กริด CSS สามารถใช้เพื่อกำหนดส่วน main และส่วนด้าน aside ของเลย์เอาต์ ซึ่งเหมาะสำหรับกริด ด้วยเหตุนี้ ความสูงของส่วนด้าน aside จะเท่ากับความสูงขององค์ประกอบ main แม้ว่าจะว่างเปล่าก็ตาม

ในการแก้ไขปัญหานี้ ให้จัดแนวองค์ประกอบด้าน aside กับจุดเริ่มต้นของพาเรนต์ เพื่อไม่ให้ส่วนสูงขยาย

 .wrapper { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-gap: 20px; } // align-self will tell the aside element to align itself with the start of its parent. aside { grid-column: 1 / 4; grid-row: 1; align-self: start; } main { grid-column: 4 / 13; } 
(ตัวอย่างขนาดใหญ่)

ดูปากกาหลักและด้านข้างโดย Ahmad Shadeed (@shadeed) บน CodePen

ดูปากกาหลักและด้านข้างโดย Ahmad Shadeed (@shadeed) บน CodePen

11. เพิ่มการ fill ให้กับ SVG

บางครั้ง ขณะทำงานกับ SVG การ fill จะไม่ทำงานตามที่คาดไว้ หากมีการเพิ่มแอตทริบิวต์การ fill แบบอินไลน์ใน SVG ในการแก้ปัญหานี้ ให้ลบแอตทริบิวต์การ fill ออกจาก SVG เองหรือแทนที่การ fill: color

ยกตัวอย่างนี้:

 .some-icon { fill: #137cbf; }

สิ่งนี้จะไม่ทำงานหาก SVG มีการเติมแบบอินไลน์ ควรเป็นสิ่งนี้แทน:

 .some-icon path { fill: #137cbf; }

12. การทำงานกับองค์ประกอบหลอก

ฉันชอบที่จะใช้องค์ประกอบหลอกทุกครั้งที่ทำได้ พวกเขาให้วิธีสร้างองค์ประกอบปลอมแก่เรา ส่วนใหญ่ใช้เพื่อการตกแต่ง โดยไม่ต้องเพิ่มลงใน HTML

เมื่อทำงานกับพวกเขา ผู้เขียนอาจลืมทำอย่างใดอย่างหนึ่งต่อไปนี้:

  • เพิ่ม content: "" คุณสมบัติ
  • กำหนด width และ height โดยไม่ต้องกำหนดคุณสมบัติการ display

ในตัวอย่างด้านล่าง เรามีชื่อที่มีตราสัญลักษณ์เป็นองค์ประกอบเทียม content: "" ควรเพิ่มคุณสมบัติ นอกจากนี้ องค์ประกอบควรมี display: inline-block set เพื่อให้ width และ height ทำงานได้ตามที่คาดไว้

ตัวอย่างขนาดใหญ่

13. พื้นที่แปลก ๆ เมื่อใช้ display: inline-block

การตั้งค่าองค์ประกอบสองรายการขึ้นไปเพื่อ display: inline-block หรือ display: inline จะสร้างช่องว่างเล็ก ๆ ระหว่างแต่ละรายการ มีการเว้นวรรคเนื่องจากเบราว์เซอร์กำลังตีความองค์ประกอบต่างๆ เป็นคำ ดังนั้นจึงเพิ่มช่องว่างระหว่างอักขระแต่ละตัว

ในตัวอย่างด้านล่าง แต่ละรายการมีพื้นที่ 8px ทางด้านขวา แต่พื้นที่เล็ก ๆ ที่เกิดจากการใช้ display: inline-block ทำให้เป็น 12px ซึ่งไม่ใช่ผลลัพธ์ที่ต้องการ

 li:not(:last-child) { margin-right: 8px; } 
(ตัวอย่างขนาดใหญ่)

การแก้ไขอย่างง่ายสำหรับสิ่งนี้คือการตั้งค่า font-size: 0 บนองค์ประกอบหลัก

 ul { font-size: 0; } li { font-size: 16px; /*The font size should be reassigned here because it will inherit `font-size: 0` from its parent.*/ } 
(ตัวอย่างขนาดใหญ่)

ดู Pen Inline Block Spacing โดย Ahmad Shadeed (@shadeed) บน CodePen

ดู Pen Inline Block Spacing โดย Ahmad Shadeed (@shadeed) บน CodePen

14. เพิ่ม for="ID" เมื่อกำหนดองค์ประกอบป้ายกำกับให้กับอินพุต

เมื่อทำงานกับองค์ประกอบของฟอร์ม ตรวจสอบให้แน่ใจว่าองค์ประกอบ label ทั้งหมดมี ID ที่กำหนดให้กับองค์ประกอบเหล่านั้น ซึ่งจะทำให้เข้าถึงได้มากขึ้น และเมื่อคลิกแล้ว ข้อมูลที่เกี่ยวข้องจะได้รับโฟกัส

 <label for="emailAddress">Email address:</label> <input type="email"> 
ตัวอย่างขนาดใหญ่

15. แบบอักษรไม่ทำงานกับองค์ประกอบ HTML เชิงโต้ตอบ

เมื่อกำหนดแบบอักษรให้กับทั้งเอกสาร แบบอักษรจะไม่ถูกนำไปใช้กับองค์ประกอบต่างๆ เช่น input , button , select และ textarea ค่าเหล่านี้ไม่ได้สืบทอดมาโดยค่าเริ่มต้น เนื่องจากเบราว์เซอร์ใช้แบบอักษรเริ่มต้นของระบบกับพวกเขา

ในการแก้ไขปัญหานี้ กำหนดคุณสมบัติฟอนต์ด้วยตนเอง:

 input, button, select, textarea { font-family: your-awesome-font-name; }

16. แถบเลื่อนแนวนอน

องค์ประกอบบางอย่างจะทำให้แถบเลื่อนแนวนอนปรากฏขึ้น เนื่องจากความกว้างขององค์ประกอบเหล่านั้น

วิธีที่ง่ายที่สุดในการค้นหาสาเหตุของปัญหานี้คือการใช้โครงร่าง CSS Addy Osmani ได้แบ่งปันสคริปต์ที่มีประโยชน์มากซึ่งสามารถเพิ่มลงในคอนโซลของเบราว์เซอร์เพื่อร่างองค์ประกอบทุกอย่างในหน้า

 [].forEach.call($$("*"), function(a) { a.style.outline = "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16); }); 
(ตัวอย่างขนาดใหญ่)

17. รูปภาพที่บีบอัดหรือยืดออก

เมื่อคุณปรับขนาดรูปภาพใน CSS รูปภาพนั้นอาจถูกบีบอัดหรือยืดออกได้หากอัตราส่วนภาพไม่สอดคล้องกับความกว้างและความสูงของรูปภาพ

วิธีแก้ปัญหานั้นง่ายมาก: ใช้ CSS ' object-fit ฟังก์ชันการทำงานคล้ายกับ background-size: cover สำหรับภาพพื้นหลัง

 img { object-fit: cover; } 
(ตัวอย่างขนาดใหญ่)

การใช้ object-fit อาจไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์แบบในทุกกรณี รูปภาพบางรูปต้องปรากฏโดยไม่ต้องครอบตัดหรือปรับขนาด และบางแพลตฟอร์มบังคับให้ผู้ใช้อัปโหลดหรือครอบตัดรูปภาพในขนาดที่กำหนด ตัวอย่างเช่น Dribbble ยอมรับการอัปโหลดภาพขนาดย่อที่ 800 x 600 พิกเซล

18. เพิ่ม type ที่ถูกต้องสำหรับ input

ใช้ type ที่ถูกต้องสำหรับช่อง input สิ่งนี้จะปรับปรุงประสบการณ์ผู้ใช้ในเบราว์เซอร์มือถือและทำให้ผู้ใช้สามารถเข้าถึงได้มากขึ้น

นี่คือ HTML บางส่วน:

 <form action=""> <p> <label for="name">Full name</label> <input type="text" id="name"> </p> <p> <label for="email">Email</label> <input type="email" id="email"> </p> <p> <label for="phone">Phone</label> <input type="tel" id="phone"> </p> </form>

นี่คือลักษณะของอินพุตแต่ละรายการเมื่อโฟกัสแล้ว:

(ตัวอย่างขนาดใหญ่)

19. หมายเลขโทรศัพท์ในรูปแบบ RTL

เมื่อเพิ่มหมายเลขโทรศัพท์ เช่น + 972-123555777 ในรูปแบบจากขวาไปซ้าย สัญลักษณ์บวกจะอยู่ท้ายหมายเลข หากต้องการแก้ไข ให้กำหนดทิศทางของหมายเลขโทรศัพท์ใหม่

 p { direction: ltr; } 
(ตัวอย่างขนาดใหญ่)

บทสรุป

ปัญหาทั้งหมดที่กล่าวถึงในที่นี้เป็นปัญหาทั่วไปที่ฉันพบในงานพัฒนาส่วนหน้าของฉัน เป้าหมายของฉันคือเก็บรายการไว้ตรวจสอบเป็นประจำขณะทำงานในโครงการบนเว็บ

คุณมีปัญหาที่คุณต้องเผชิญใน CSS เสมอหรือไม่? แจ้งให้เราทราบในความคิดเห็น!