บทสรุปของโพสต์โดย durumis AI
- ได้นำเสนอวิธีแก้ไขปัญหา Cross-Browsing ที่เกิดขึ้นในเบราว์เซอร์ Safari ในระหว่างการพัฒนาเว็บมือถือ ซึ่งรวมถึงปัญหาการคำนวณความสูงของ Viewport และปัญหา UI เลื่อนเนื่องจากแป้นพิมพ์เสมือนจริง
- ปัญหาความสูงของ Viewport สามารถแก้ไขได้โดยใช้ dvh หรือ svh ปัญหาแป้นพิมพ์เสมือนจริงสามารถแก้ไขได้โดยใช้ min-height การใช้ Vendor Prefix และการควบคุมแบบไดนามิกโดยใช้ JavaScript
- ในการพัฒนาเว็บมือถือ Safari ควรคำนึงถึงการใช้ Vendor Prefix ข้อจำกัดของ LocalStorage และ SessionStorage (ประมาณ 5MB) และการไม่สามารถแชร์ Storage ระหว่างแท็บได้
เขียนโพสต์อย่างตั้งใจแล้วกดบันทึก แต่ดันขึ้น 404 แล้วหายไป ㅠㅠ
ขณะพัฒนาเว็บมือถือ ฉันได้พบกับปัญหา cross-browsing 2 ข้อที่น่าปวดหัว และประเด็นอื่นๆ ที่ต้องพิจารณา
ปัญหาการคำนวณความสูงของ viewport ที่เกิดจากแถบที่อยู่และแถบนำทางของเบราว์เซอร์เอง
Safari และ Samsung Internet มีแถบนำทางด้านล่างอยู่ภายในเบราว์เซอร์เอง เว้นแต่จะมีการตั้งค่า show/hide โดยเฉพาะ เมื่อเลื่อนลง แถบนำทางจะปรากฏขึ้น และเมื่อเลื่อนขึ้น แถบนำทางจะหายไป
ปัญหาคือ สิ่งเหล่านี้ทำให้ viewport ไม่คงที่และเปลี่ยนแปลงไป
ตัวอย่างเช่น หากกำหนดความสูงเป็น 100vh ในกรณีที่ไม่มีแถบนำทาง レイアウトจะแสดงอย่างถูกต้อง แต่ถ้าแถบนำทางปรากฏขึ้น แถบนำทางจะปิดบัง UI เกิดเป็นปัญหาขึ้น
dvh คือ viewport แบบไดนามิก ซึ่งจะสะท้อนการเปลี่ยนแปลงโดยอัตโนมัติเมื่อความสูงของ viewport เปลี่ยนแปลง ดังนั้นจึงสามารถตอบสนองต่อการเปลี่ยนแปลงของレイアウト UI ตามการมีหรือไม่มีแถบที่อยู่หรือแถบนำทางด้านล่างได้
2. สามารถพิจารณา svh ได้เช่นกัน
svh คือความสูงของพื้นที่ UI อย่างแท้จริง โดยไม่รวมแถบที่อยู่หรือแถบนำทาง ในสถานการณ์ที่คาดว่าแถบที่อยู่หรือแถบนำทางจะปรากฏขึ้น การใช้ svh จะมีความแม่นยำมากขึ้น
ปัญหา UI เลื่อนเนื่องจากแป้นพิมพ์เสมือนเมื่อเลือก input
ใน Safari บนมือถือ เมื่อเลือก input ปัญหา UI เลื่อนเนื่องจากแป้นพิมพ์เสมือนเกิดขึ้น ในเบราว์เซอร์อื่นๆ โดยทั่วไป แป้นพิมพ์เสมือนจะปรากฏแบบ absolute แต่ใน Safari เว็บมือถือ ดูเหมือนว่าจะใช้ display block จึงใช้พื้นที่
Safari ปรับความสูงของ viewport แบบไดนามิกเมื่อแป้นพิมพ์เสมือนปรากฏขึ้น ทำให้เกิดปัญหาเนื่องจากองค์ประกอบที่ใช้หน่วย vh ถูกปรับใหม่ เพื่อแก้ไขปัญหานี้
ยึดความสูงเพื่อป้องกันไม่ให้ UI เลื่อน
html, body {
height: 100%;
min-height: 100vh; /* กำหนดความสูงต่ำสุดคงที่ */
overflow: hidden;
}
2. ใช้ vendor prefix (อธิบายเพิ่มเติมด้านล่าง)
html, body {
height: -webkit-fill-available; /* สำหรับ Safari */
}
แทรกแอตทริบิวต์ที่ใช้ในเบราว์เซอร์เฉพาะ เช่น Safari
3. ควบคุม viewport แบบไดนามิกด้วย JavaScript
window.addEventListener('resize', () => {
if (window.innerHeight < 500) {
// รหัสที่จะทำงานเมื่อแป้นพิมพ์ปรากฏขึ้น
document.body.classList.add('keyboard-visible');
} else {
// รหัสที่จะทำงานเมื่อแป้นพิมพ์หายไป
document.body.classList.remove('keyboard-visible');
}
});
ติดตั้ง event resize เพื่อตรวจจับการเปลี่ยนแปลงของ viewport และใช้สไตล์ที่เหมาะสม
3-1. ควบคุมตำแหน่งเมื่อเกิด event focusin
document.querySelectorAll('input, textarea').forEach(element => {
element.addEventListener('focusin', () => {
setTimeout(() => {
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
}, 100);
});
});
3-2. ควบคุมตำแหน่งเมื่อแป้นพิมพ์เสมือนปรากฏขึ้น (ตัวอย่างด้านล่างใช้การเพิ่ม class)
let originalHeight = window.innerHeight;
window.addEventListener('resize', () => {
if (window.innerHeight < originalHeight) {
// สถานะที่แป้นพิมพ์เสมือนปรากฏขึ้น
document.body.classList.add('keyboard-visible');
} else {
// สถานะที่แป้นพิมพ์เสมือนหายไป
document.body.classList.remove('keyboard-visible');
}
});
ฉันแก้ปัญหาด้วยวิธีที่ 3-1 หากวิธีที่ 3-1 ไม่ทำงานตามที่ต้องการ ให้ลองใช้โค้ดด้านล่างเพื่อตรวจสอบก่อนว่าถูกต้องหรือไม่
window.addEventListener('focusin', () => {
setTimeout(()=> {
window.scrollTo(0,0)
}, 100);
})
อื่นๆ
นอกจากนี้ ฉันยังได้ค้นหาข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่ควรพิจารณาเมื่อพัฒนาเว็บมือถือสำหรับ Safari
1. ใช้ vendor prefix เมื่อใช้แอตทริบิวต์บางอย่าง
* vendor prefix คือคำนำหน้าที่ช่วยให้เบราว์เซอร์เข้าใจและแสดงผลแอตทริบิวต์ css บางอย่างได้ โดยใช้เพื่อให้ css ที่มีการใช้งานที่แตกต่างกันในเบราว์เซอร์ต่างๆ ทำงานได้ตามที่ตั้งใจ ด้วยวิธีนี้จะช่วยให้เกิดความสอดคล้องกันระหว่างเบราว์เซอร์ต่างๆ และยังสามารถใช้งานร่วมกับเบราว์เซอร์เวอร์ชันเก่าได้อีกด้วย
-webkit-: Chrome, Safari ฯลฯ
-moz-: Mozilla Firefox
-ms-: Internet Explorer และ Edge
-o-: Opera
แอตทริบิวต์ทั่วไปที่ต้องการ vendor prefix มีดังนี้
.container {
display: -webkit-flex; /* Safari */
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
}
.item {
-webkit-flex-grow: 1; /* Safari */
flex-grow: 1;
-webkit-flex-shrink: 1; /* Safari */
flex-shrink: 1;
}
.grid-container {
display: -ms-grid; /* IE11 และเบราว์เซอร์เวอร์ชันเก่า */
display: grid; / เบราว์เซอร์เวอร์ชันใหม่ */
}
.sticky-element {
position: -webkit-sticky; /* Safari */
position: sticky;
}
input[type="text"],
select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
นอกจากนี้ Safari ยังจำกัดขนาดของ LocalStorage และ SessionStorage ไว้ที่ประมาณ 5 MB และไม่แชร์พื้นที่เก็บข้อมูลระหว่างแท็บต่างๆ ดังนั้นจึงควรระมัดระวัง
ps. เสียใจมากที่โพสต์ที่เขียนไว้หายไป โพสต์ที่ฉันอัปโหลดอาจไม่ได้มีคุณภาพดีมากนัก แต่...ㅠ ต้องบันทึกชั่วคราวให้ได้แล้ว