ภาพพื้นหลังจะกระโดดเมื่อแถบที่อยู่ซ่อน iOS / Android / Mobile Chrome


174

ฉันกำลังพัฒนาเว็บไซต์ที่ตอบสนองโดยใช้ Twitter Bootstrap

ไซต์นี้มีภาพพื้นหลังแบบเต็มหน้าจอในอุปกรณ์เคลื่อนที่ / แท็บเล็ต / เดสก์ท็อป ภาพเหล่านี้หมุนและจางหายไปโดยใช้สอง divs

มันเกือบจะสมบูรณ์แบบยกเว้นเรื่องเดียว การใช้ iOS Safari, เบราว์เซอร์ Android หรือ Chrome บน Android พื้นหลังจะกระโดดเล็กน้อยเมื่อผู้ใช้เลื่อนหน้าลงและทำให้แถบที่อยู่ซ่อน

เว็บไซต์อยู่ที่นี่: http://lt2.daveclarke.me/

ไปที่อุปกรณ์พกพาแล้วเลื่อนลงและคุณจะเห็นภาพมีขนาด / ย้าย

รหัสที่ฉันใช้สำหรับพื้นหลัง DIV มีดังนี้:

#bg1 {
    background-color: #3d3d3f;
    background-repeat:no-repeat;
    background-attachment:fixed;
    background-position:center center;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover; position:fixed;
    width:100%;
    height:100%;
    left:0px;
    top:0px;
    z-index:-1;
    display:none;
}

ยินดีต้อนรับคำแนะนำทั้งหมด - สิ่งนี้ทำให้หัวของฉันในขณะที่ !!


ลิงก์ของคุณต้องการการรับรองความถูกต้อง ... โปรดแสดงรหัสให้เราด้วย!
Shawn Taylor

การเชื่อมโยงใหม่ที่เพิ่มและแสดงรหัสสำหรับการวางตำแหน่งพื้นหลัง ฯลฯ
เดฟคล๊าร์ค

1
หากคุณกำลังประสบปัญหานี้คุณอาจต้องการตรวจสอบdevelopers.google.com/web/updates/2016/12/url-bar-resizing ปัญหานี้มี (ประเภท) ได้รับการแก้ไขในขณะนี้ position: fixedแต่ยังคงส่งผลกระทบต่อองค์ประกอบที่มี
Adam Reis

@ AdamReis ในที่สุด! ขอบคุณสำหรับการโพสต์
เดฟคลาร์ก

คำตอบ:


106

ปัญหานี้เกิดจากแถบ URL ย่อขนาด / เลื่อนออกและเปลี่ยนขนาดของ # bg1 และ # bg2 divs เนื่องจากมีความสูง 100% และ "คงที่" เนื่องจากภาพพื้นหลังถูกตั้งค่าเป็น "หน้าปก" มันจะปรับขนาด / ตำแหน่งของภาพเนื่องจากพื้นที่ที่มีขนาดใหญ่กว่า

ขึ้นอยู่กับลักษณะการตอบสนองของเว็บไซต์พื้นหลังจะต้องปรับขนาด ฉันชอบวิธีแก้ปัญหาสองประการที่เป็นไปได้:

1) ตั้งค่า # bg1, # bg2 height เป็น 100vh ในทางทฤษฎีแล้วนี่เป็นคำตอบที่สง่างาม อย่างไรก็ตาม iOS มีข้อผิดพลาด vh ( http://thatemil.com/blog/2013/06/13/viewport-relative-unit-strangeness-in-ios-6/ ) ฉันพยายามใช้ความสูงสูงสุดเพื่อป้องกันปัญหานี้ แต่ยังคงอยู่

2) ขนาดวิวพอร์ตเมื่อพิจารณาจาก Javascript จะไม่ได้รับผลกระทบจากแถบ URL ดังนั้น Javascript สามารถใช้เพื่อตั้งค่าความสูงคงที่ใน # bg1 และ # bg2 ตามขนาดวิวพอร์ต นี่ไม่ใช่ทางออกที่ดีที่สุดเนื่องจากไม่ใช่ CSS ที่บริสุทธิ์และมีการข้ามภาพเล็กน้อยเมื่อโหลดหน้าเว็บ อย่างไรก็ตามมันเป็นทางออกเดียวที่ฉันเห็นเมื่อพิจารณาข้อบกพร่อง "vh" ของ iOS (ซึ่งดูเหมือนว่าจะไม่ได้รับการแก้ไขใน iOS 7)

var bg = $("#bg1, #bg2");

function resizeBackground() {
    bg.height($(window).height());
}

$(window).resize(resizeBackground);
resizeBackground();

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

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

function resizeBackground() {
    bg.height( $(window).height() + 60);
}

ขอบคุณสำหรับสิ่งนี้. พรุ่งนี้ฉันจะให้มันหมุนวนแล้วบอกให้คุณรู้ว่าฉันจะไปได้ยังไง :)
เดฟคลาร์

5
มันวิเศษมาก ฉันใช้โซลูชันที่สองของคุณซึ่งทำงานได้อย่างสมบูรณ์แบบเกือบจะมีช่องว่างเพียงไม่กี่พิกเซลระหว่างส่วนท้ายและภาพพื้นหลัง ฉันเปลี่ยนรหัสบรรทัดที่ 4 ของคุณเป็น: bg.height(jQuery(window).height() + 60);ซึ่งใช้ได้กับอุปกรณ์ของฉันทั้งหมด! ขอบคุณ :)
Dave Clarke

6
ข้อผิดพลาด iOS vh ได้รับการแก้ไขใน iOS8 แต่ปัญหาบน Android ไม่ใช่ ฉันใช้vhหน่วยและแน่นอน100vhใหญ่กว่าเมื่อซ่อนแถบที่อยู่ มันโง่ที่การกระโดดนี้เกิดขึ้นหลังจากการเลื่อนหยุด มันดูบั๊กกี้ ฉันลงเอยด้วยการเปลี่ยนที่ความสูงเพื่อให้ดูเหมือนเป็นความตั้งใจ
ProblemsOfSumit

1
ฉันสามารถแก้ปัญหานี้ได้โดยการย้ายพื้นหลังจากbodyไปเป็น wrapper <div>ห่อเนื้อหาทั้งหมดของหน้า ไม่มีพื้นหลังกระโดดบน iOS หรือ Android!
Marius Schulz

2
โซลูชัน JS ไม่ทำงานสำหรับฉัน (Android) ยืนยันว่าสคริปต์กำลังตั้งค่าความสูง แต่ปัญหายังคงมีอยู่
jwinn

61

ฉันพบว่าคำตอบของ Jason ไม่ได้ผลสำหรับฉันและฉันยังคงได้รับการกระโดด Javascript ทำให้มั่นใจได้ว่าไม่มีช่องว่างที่ด้านบนของหน้า แต่พื้นหลังยังคงกระโดดเมื่อใดก็ตามที่แถบที่อยู่หายไป / ปรากฏขึ้นอีกครั้ง ดังนั้นการแก้ไข Javascript ฉันจึงใช้transition: height 999999sกับ div สิ่งนี้จะสร้างช่วงการเปลี่ยนภาพที่มีระยะเวลานานจนทำให้องค์ประกอบนั้นหยุดนิ่ง


23
คุณสมควรได้รับ +1 สำหรับการคิดนอกกรอบที่แท้จริง น่าเสียดายที่นี่ช่วยป้องกันการปรับขนาด div เป็นการเปลี่ยนแปลงขนาดหน้าจอรวมถึงตัวอย่างที่เกิดจากการหมุนหน้าจอ
tobik

+1 สำหรับความคิดสร้างสรรค์! อาจต้องใช้สิ่งนี้ในตอนนี้เนื่องจากสารประกอบออกหากคุณใช้vwหรือvhตั้งค่าขนาดตัวอักษรภายในคอนเทนเนอร์หลัก
robabby

6
@tobik มันยังคงเป็นไปได้ที่จะลดการกระโดดที่เกิดจากการเปลี่ยนวิวพอร์ตโดยตั้งค่าการเปลี่ยน 0.5 วินาทีหรือมากกว่านั้น
binaryfunt

7
พยายามหมุนโทรศัพท์ตอนนี้
cuddlecheek

1
@tobik นี้จริงทำให้มันมากขึ้นกว่าคุณลักษณะข้อผิดพลาดที่;) การคิดที่ดี
dimitrieh

23

ฉันมีปัญหาที่คล้ายกันในส่วนหัวของเว็บไซต์ของเรา

html, body {
    height:100%;
}
.header {
    height:100%;
}

สิ่งนี้จะจบลงด้วยประสบการณ์การเลื่อนที่น่ากลัวสำหรับ Android chrome เนื่องจาก. header header จะ rescale หลังจากการซ่อน url-bar และนิ้วถูกลบออกจากหน้าจอ

CSS-การแก้ไข:

การเพิ่มสองบรรทัดต่อไปนี้จะป้องกันไม่ให้แถบ url-bar และการเลื่อนแนวตั้งยังคงเป็นไปได้:

html {
    overflow: hidden;
}
body {
    overflow-y: scroll;
    -webkit-overflow-scrolling:touch;
}

4
ใช่มันแก้ได้เหมือนที่คุณพูด แต่มันแย่มากที่แถบนำทางแสดงตลอดเวลา ในโทรศัพท์บางรุ่นอาจใช้พื้นที่หน้าจอที่มีค่ามาก!
Dave Clarke

1
ที่จริงเพื่อป้องกันสิ่งนี้คุณสามารถใช้ JavaScript-Workaround เพิ่มเติมได้ แต่ตัวอย่างนี้ใช้ได้โดยไม่มี JS เลย
พรม

3
เลื่อนถูกปิดใช้งานอย่างสมบูรณ์เมื่อฉันลองวิธีนี้
นิธินเบบี้

1
ขอบคุณที่ใช้งานได้ดีกับสถานการณ์ของฉัน! ควรถูกกล่าวถึงสำหรับคนอื่น ๆ ที่อาจพลาดได้ว่าแท็ก html และ body ต้องถูกตั้งไว้ที่ความสูง 100% เพื่อให้ทำงานได้
เสน่ห์ใน

-webkit-overflow-scrolling ไม่ควรใช้กับไซต์การผลิต developer.mozilla.org/en-US/docs/Web/CSS/…
Fredrik Westerlund

16

ปัญหาสามารถแก้ไขได้ด้วยแบบสอบถามสื่อและคณิตศาสตร์บางอย่าง นี่เป็นวิธีแก้ปัญหาสำหรับการวางแนว portait:

@media (max-device-aspect-ratio: 3/4) {
  height: calc(100vw * 1.333 - 9%);
}
@media (max-device-aspect-ratio: 2/3) {
  height: calc(100vw * 1.5 - 9%);
}
@media (max-device-aspect-ratio: 10/16) {
  height: calc(100vw * 1.6 - 9%);
}
@media (max-device-aspect-ratio: 9/16) {
  height: calc(100vw * 1.778 - 9%);
}

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

1) สร้างชุดการสืบค้นสื่อสำหรับอัตราส่วนภาพที่คุณต้องการกำหนดเป้าหมาย

  • ใช้อุปกรณ์อัตราส่วนภาพแทนอัตราส่วนกว้างยาวเพราะหลังจะปรับขนาดเมื่อแถบ URL หายไป

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

  • จำคำค้นหาสื่อโดยใช้แนวนอน / แนวตั้งดังนั้นสำหรับการถ่ายคุณจะต้องพลิกตัวเลข

2) สำหรับแต่ละเคียวรี่สื่อบันทึกคูณเปอร์เซ็นต์ของความสูงในแนวดิ่งที่คุณต้องการให้องค์ประกอบอยู่ใน vw ด้วยการย้อนกลับของอัตราส่วนกว้างยาว

  • เมื่อคุณทราบความกว้างและอัตราส่วนของความกว้างต่อความสูงคุณเพียงแค่คูณ% ที่คุณต้องการ (100% ในกรณีของคุณ) ด้วยอัตราส่วนของความสูง / ความกว้าง

3) คุณต้องกำหนดความสูงของแถบ URL และลบจากความสูง ฉันไม่พบการวัดที่แน่นอน แต่ฉันใช้ 9% สำหรับอุปกรณ์มือถือในแนวนอนและดูเหมือนว่าจะทำงานได้ดีพอสมควร

นี่ไม่ใช่วิธีการแก้ปัญหาที่หรูหรามาก แต่ตัวเลือกอื่น ๆ ก็ไม่ได้ดีมากนักเนื่องจากเป็น:

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

  • มีองค์ประกอบที่มีขนาดไม่ถูกต้องหรือ

  • การใช้จาวาสคริปต์สำหรับพื้นฐานบางอย่างสไตล์

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

เพื่อให้ง่ายขึ้นฉันยังได้สร้าง SASS mixin:

@mixin vh-fix {
  @media (max-device-aspect-ratio: 3/4) {
    height: calc(100vw * 1.333 - 9%);
  }
  @media (max-device-aspect-ratio: 2/3) {
    height: calc(100vw * 1.5 - 9%);
  }
  @media (max-device-aspect-ratio: 10/16) {
    height: calc(100vw * 1.6 - 9%);
  }
  @media (max-device-aspect-ratio: 9/16) {
    height: calc(100vw * 1.778 - 9%);
  }
}

2
สร้างสรรค์มาก! ไม่ใช่แฟนของการคาดเดา 9%
w00t

1
ง่ายและสมาร์ท! คุณสามารถเพิ่มพารามิเตอร์ลงใน vh-fix เพื่อจำลองพฤติกรรมดั้งเดิม: @mixin vh-fix($vh: 100)=>height: calc(100vw * (1.333 * $vh / 100) - 9%)
mjsarfatti

1
ด้านบนควรเป็น:height: calc(100vw * (1.333 * #{$vh} / 100) - 9%)
mjsarfatti

-9%สำหรับกรณีการใช้งานของฉันนี้ทำงานได้ดีจริงๆและดียิ่งขึ้นเมื่อฉันออก
เบ็นเฟลมมิ่ง

12

คำตอบทั้งหมดที่นี่ใช้windowความสูงซึ่งได้รับผลกระทบจากแถบ URL ทุกคนลืมscreenความสูงได้ไหม?

นี่คือโซลูชัน jQuery ของฉัน:

$(function(){

  var $w = $(window),
      $background = $('#background');

  // Fix background image jump on mobile
  if ((/Android|iPhone|iPad|iPod|BlackBerry/i).test(navigator.userAgent || navigator.vendor || window.opera)) {
    $background.css({'top': 'auto', 'bottom': 0});

    $w.resize(sizeBackground);
    sizeBackground();
  }

  function sizeBackground() {
     $background.height(screen.height);
  }
});

การเพิ่มชิ้น.css()ส่วนคือการเปลี่ยนองค์ประกอบตำแหน่งที่แน่นอนที่สุดที่จัดอยู่ในแนวด้านบนเป็นแนวด้านล่างอย่างหลีกเลี่ยงไม่ได้เลย แม้ว่าฉันคิดว่าไม่มีเหตุผลที่จะไม่เพียงแค่เพิ่มสิ่งนั้นลงใน CSS ปกติโดยตรง

เราต้องการตัวแทนผู้ใช้ดมกลิ่นเพราะความสูงของหน้าจอบนเดสก์ท็อปจะไม่เป็นประโยชน์

นอกจากนี้ทั้งหมดนี้เป็นข้อสมมติ #backgroundเป็นองค์ประกอบตำแหน่งคงที่เติมหน้าต่าง

สำหรับ purists JavaScript (คำเตือน - ยังไม่ทดลอง):

var background = document.getElementById('background');

// Fix background image jump on mobile
if ((/Android|iPhone|iPad|iPod|BlackBerry/i).test(navigator.userAgent || navigator.vendor || window.opera)) {
  background.style.top = 'auto';
  background.style.bottom = 0;

  window.onresize = sizeBackground;
  sizeBackground();
}

function sizeBackground() {
  background.style.height = screen.height;
}

แก้ไข: ขออภัยที่นี่ไม่ได้ตอบปัญหาของคุณโดยตรงที่มีมากกว่าหนึ่งพื้นหลัง แต่นี่เป็นหนึ่งในผลลัพธ์แรกเมื่อค้นหาปัญหาของพื้นหลังคงที่ที่กระโดดบนมือถือ


2
ฉันลองตอบคำถามเหล่านี้เป็นล้านคำตอบและนี่ก็เป็นสิ่งที่ดีที่สุด เดิมทีฉันพยายามใช้สิ่งนี้กับ <body> เพราะมีพื้นหลัง การใช้ div เพื่อตัดทั้งหน้าทำให้เกิดปัญหาอื่น ใช้ div ที่ว่างเปล่ากับ z-index: -1 เนื่องจากพื้นหลังดูเหมือนจะเป็นทางออกที่ดีที่สุดเมื่อรวมกับด้านบน ฉันลบการตรวจจับมือถือออกเนื่องจากการทำเช่นนี้บนเดสก์ท็อปไม่ได้ส่งผลเสียต่อเว็บไซต์ของฉัน ไม่มีคณิตศาสตร์ (ซึ่งสามารถเดาขนาดของแท็บผิด) ไม่จำเป็นต้องใช้ตัวจัดการสำหรับการปรับขนาด พื้นหลังเป็นเพียงหน้าจอทั้งหมดทอดสมอไว้ที่ด้านล่าง เสร็จสิ้น รักมัน!
Evan Langlois

9

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

1) องค์ประกอบที่มีการตั้งค่าความสูงเพื่อ100vhปรับขนาดทุกครั้งที่การเปลี่ยนแปลงขนาดวิวพอร์ตรวมถึงกรณีเหล่านั้นเมื่อมันเกิดจาก (dis) ปรากฏแถบ URL

2) $(window).height()ส่งคืนค่าที่ได้รับผลกระทบจากขนาดของแถบ URL

ทางออกหนึ่งคือการ "แช่แข็ง" องค์ประกอบโดยใช้transition: height 999999sเป็นข้อเสนอแนะในคำตอบโดย AlexKempton ข้อเสียคือการปิดใช้งานการปรับขนาดให้เหมาะสมกับการเปลี่ยนแปลงขนาดวิวพอร์ตทั้งหมดรวมถึงสิ่งที่เกิดจากการหมุนหน้าจอ

ดังนั้นโซลูชันของฉันคือจัดการการเปลี่ยนแปลงวิวพอร์ตด้วยตนเองโดยใช้ JavaScript สิ่งนี้ทำให้ฉันสามารถเพิกเฉยต่อการเปลี่ยนแปลงเล็ก ๆ ที่อาจเกิดขึ้นจากแถบ URL และตอบสนองต่อการเปลี่ยนแปลงขนาดใหญ่เท่านั้น

function greedyJumbotron() {
    var HEIGHT_CHANGE_TOLERANCE = 100; // Approximately URL bar height in Chrome on tablet

    var jumbotron = $(this);
    var viewportHeight = $(window).height();

    $(window).resize(function () {
        if (Math.abs(viewportHeight - $(window).height()) > HEIGHT_CHANGE_TOLERANCE) {
            viewportHeight = $(window).height();
            update();
        }
    });

    function update() {
        jumbotron.css('height', viewportHeight + 'px');
    }

    update();
}

$('.greedy-jumbotron').each(greedyJumbotron);

แก้ไข: height: 100vhที่จริงผมใช้เทคนิคนี้ร่วมกับ หน้าจะแสดงผลอย่างถูกต้องตั้งแต่เริ่มต้นจากนั้นจาวาสคริปต์จะเริ่มทำงานและเริ่มจัดการความสูงด้วยตนเอง วิธีนี้ไม่มีการกระพริบเลยในขณะที่กำลังโหลดหน้า (หรือหลังจากนั้น)


1
ฉันใช้สิ่งที่คล้ายกัน แต่แทนที่จะตั้งค่าheight: 100vhใน CSS เริ่มต้นฉันตั้งค่าmin-height:100vhและจากนั้นปรับขนาดหน้าต่างฉันคำนวณmin-heightและตั้งเป็นความสูงของพอร์ตการดู สิ่งนี้มีประโยชน์เมื่อไซต์ของคุณดูบนหน้าจอขนาดเล็กและเนื้อหามีขนาดใหญ่เกินกว่าที่จะพอดีกับวิวพอร์ต การ debounce / throttle setTimeout สำหรับเหตุการณ์การปรับขนาดช่วยปรับปรุงประสิทธิภาพการทำงานของเบราว์เซอร์บางตัว (การปรับขนาดมีแนวโน้มที่จะยิงบ่อยครั้ง)
Troy Morehouse

ฉันคิดว่าในบางจุดฉันก็ลองใช้min-heightแทน แต่แล้วฉันก็พบปัญหาเมื่อฉันต้องการจัดตำแหน่งเนื้อหาในแนวตั้ง อย่างใดแนวตั้งตรงกลางจะได้รับหากินเมื่อองค์ประกอบด้านนอกมีการตั้งค่าให้height autoดังนั้นฉันจึงมีความสูงขั้นต่ำคงที่ซึ่งเพียงพอที่จะมีเนื้อหาประเภทใด ๆ ที่เป็นไปได้และตั้งไว้ใน CSS เริ่มต้น เนื่องจากmin-heightมีลำดับความสำคัญสูงกว่าheightจึงใช้งานได้ค่อนข้างดี
tobik

อ่าใช่ฉันมีปัญหาเดียวกัน แต่คงได้โดยการเปลี่ยน jumbotron ไปdisplay: tableแล้วการตั้งค่าภาชนะบรรจุภายในด้วยdisplay: table-cell vertical-align: middleทำงานเหมือนจับใจ
ทรอยมอร์เฮาส์

จริงๆ? เพราะฉันลองวิธีเดียวกัน แต่ล้มเหลว ฉันจำไม่ได้ว่าปัญหาคืออะไร แต่สิ่งนี้อาจเกี่ยวข้อง: stackoverflow.com/questions/7790222/ …
tobik

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

8

วิธีการแก้ปัญหาที่ฉันใช้อยู่ในปัจจุบันคือตรวจสอบการuserAgentเปิด$(document).readyเพื่อดูว่าเป็นเบราว์เซอร์ที่ละเมิดหรือไม่ ถ้าเป็นเช่นนั้นทำตามขั้นตอนเหล่านี้:

  1. ตั้งค่าความสูงที่เกี่ยวข้องเป็นความสูงวิวพอร์ตปัจจุบันแทนที่จะเป็น '100%'
  2. เก็บค่าแนวนอนวิวพอร์ตปัจจุบัน
  3. จากนั้นเปิด$(window).resizeอัปเดตเฉพาะค่าความสูงที่เกี่ยวข้องหากมิติวิวพอร์ตแนวนอนใหม่แตกต่างจากค่าเริ่มต้น
  4. เก็บค่าแนวนอนและแนวตั้งใหม่

คุณสามารถเลือกที่จะทดสอบการปรับขนาดแนวดิ่งเมื่อเกินความสูงของแถบที่อยู่

Oh, $(window).heightและแถบที่อยู่ไม่ส่งผลกระทบต่อ โปรดดู: แถบที่อยู่ของเบราว์เซอร์มือถือ Webkit (chrome) เปลี่ยน $ (หน้าต่าง) .height (); ทำให้ขนาดพื้นหลัง: ปก rescale ทุกครั้งที่ JS "หน้าต่าง" กว้างสูงเทียบกับ "หน้าจอ" กว้างสูง?


ฉันไม่ได้ลองสิ่งนี้ แต่ประเด็นแรกของคุณไม่สามารถใช้กับ iOS ได้หรือไม่? ( thatemil.com/blog/2013/06/13/… )
Dave Clarke

ฉันกำลังแก้ไขเขาให้ความสำคัญในขั้นตอนแรก แต่ฉันประหลาดใจที่คุณพบการตอบสนองของ Jason ในการแก้ปัญหา ตามที่ระบุไว้ฉันพบพร้อมกับผู้ใช้คนอื่น ๆ ในคำถามก่อนหน้านี้ที่ฉันเชื่อมโยงว่าค่าวิธีการ $ (หน้าต่าง) .height () เปลี่ยนแปลงเมื่อแถบที่อยู่ในโครเมี่ยมบน android เป็นหรือมองไม่เห็น ฉันโยนไซต์เล็ก ๆ นี้ที่เพิ่งเปิดตัว $ (หน้าต่าง) .height () ส่งผลให้เกิดการแจ้งเตือนและมันมีค่าที่แตกต่างกันใน Nexus 4 ของฉันในโครเมี่ยมเมื่อแถบที่อยู่นั้นมองไม่เห็น: stormy-meadow-5908 .herokuapp.com
mp

100% นี้แก้ไขปัญหาบนอุปกรณ์ Android ของฉันแม้ว่าฉันจะเห็นปัญหาที่คล้ายกันบน iPad ของฉันซึ่งไม่ปรากฏว่าจะแก้ไขซึ่งฉันยังคงมองหา
Dave Clarke

คุณสามารถให้รหัสสำหรับการแก้ปัญหาของคุณและฉันจะลอง?
Dave Clarke

4

ฉันพบโซลูชันที่ง่ายมากโดยไม่ใช้ Javascript:

transition: height 1000000s ease;
-webkit-transition: height 1000000s ease;
-moz-transition: height 1000000s ease;
-o-transition: height 1000000s ease;

ทั้งหมดนี้ทำให้การเคลื่อนไหวเกิดความล่าช้าดังนั้นมันจึงช้าอย่างไม่น่าเชื่อ


@ Tyguy7 ปรับการทำงานเมื่อใดก็ตามที่ความสูงของคุณไม่ได้ถูกกำหนดเป็นค่าคงที่เช่น,100% 100vhIE8 เป็นเบราว์เซอร์หลักตัวเดียวที่ไม่รองรับการเปลี่ยนแปลง
Pav Sidhu

ทางออกที่ยอดเยี่ยมและเรียบง่าย!
zdarsky.peter

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

@NagyNick ที่ไม่ได้เป็นปัญหาใหญ่สำหรับฉัน คุณสามารถตรวจจับการเปลี่ยนแปลงการวางแนวใน Javascript และปรับภาพพื้นหลัง
Pav Sidhu

3

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

var $hero = $('#hero-wrapper'),
    h     = window.innerHeight;

$hero.css('height', h);

3

ฉันสร้างโซลูชันวานิลลาจาวาสคริปต์เพื่อใช้หน่วย VH การใช้ VH แทบทุกที่ได้รับผลกระทบจากแถบที่อยู่ลดการเลื่อน ในการแก้ไขปัญหาช่องว่างที่แสดงเมื่อหน้าเขียนขึ้นใหม่ฉันมี js นี้ที่นี่ที่จะจับองค์ประกอบทั้งหมดของคุณโดยใช้หน่วย VH (ถ้าคุณให้คลาส.vh-fix) และให้ความสูงพิกเซลแบบอินไลน์ เป็นหลักตรึงพวกเขาที่ระดับความสูงที่เราต้องการ คุณสามารถทำสิ่งนี้กับการหมุนหรือเปลี่ยนขนาดวิวพอร์ตเพื่อให้ตอบสนองได้ดี

var els = document.querySelectorAll('.vh-fix')
if (!els.length) return

for (var i = 0; i < els.length; i++) {
  var el = els[i]
  if (el.nodeName === 'IMG') {
    el.onload = function() {
      this.style.height = this.clientHeight + 'px'
    }
  } else {
    el.style.height = el.clientHeight + 'px'
  }
}

สิ่งนี้ได้แก้ไขกรณีการใช้งานทั้งหมดของฉันหวังว่าจะช่วยได้


3

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

//remove height property from file css because we will set it to first run of page
//insert this snippet in a script after declarations of your scripts in your index

var setHeight = function() {    
  var h = $(window).height();   
  $('#bg1, #bg2').css('height', h);
};

setHeight(); // at first run of webpage we set css height with a fixed value

if(typeof window.orientation !== 'undefined') { // this is more smart to detect mobile devices because desktop doesn't support this property
  var query = window.matchMedia("(orientation:landscape)"); //this is is important to verify if we put 
  var changeHeight = function(query) {                      //mobile device in landscape mode
    if (query.matches) {                                    // if yes we set again height to occupy 100%
      setHeight(); // landscape mode
    } else {                                                //if we go back to portrait we set again
      setHeight(); // portrait mode
    }
  }
  query.addListener(changeHeight);                          //add a listner too this event
} 
else { //desktop mode                                       //this last part is only for non mobile
  $( window ).resize(function() {                           // so in this case we use resize to have
    setHeight();                                            // responsivity resisizing browser window
  }); 
};

1
คุณกำลังเรียกใช้ setHeight () ด้านในของเมธอด changeHeight ถ้าเคียวรีตรงกันและถ้ามันไม่ตรงกัน ดังนั้นเพียงแค่ลบคำสั่ง if ตามที่ไม่จำเป็น
Dennis Meissner

2

นี่เป็นทางออกที่ดีที่สุด (ง่ายที่สุด) เหนือทุกสิ่งที่ฉันได้ลอง

... และนี่จะไม่เก็บประสบการณ์ดั้งเดิมของแถบที่อยู่ !

คุณสามารถตั้งค่าความสูงด้วย CSS เป็น 100% เช่นจากนั้นตั้งความสูงเป็น 0.9 * ของความสูงหน้าต่างใน px ด้วย javascript เมื่อโหลดเอกสาร

ตัวอย่างเช่นกับ jQuery:

$("#element").css("height", 0.9*$(window).height());

)

น่าเสียดายที่ไม่มีสิ่งใดที่ทำงานกับ CSS บริสุทธิ์: P แต่ต้องย่อขนาดลงvhและvwใช้งานบน iPhone ได้ด้วย - ใช้เปอร์เซ็นต์


1

ฉันตั้งองค์ประกอบความกว้างของฉันด้วย javascript หลังจากฉันตั้งค่า de vh

HTML

<div id="gifimage"><img src="back_phone_back.png" style="width: 100%"></div>

CSS

#gifimage {
    position: absolute;
    height: 70vh;
}

จาวาสคริปต์

imageHeight = document.getElementById('gifimage').clientHeight;

// if (isMobile)       
document.getElementById('gifimage').setAttribute("style","height:" + imageHeight + "px");

มันใช้งานได้สำหรับฉัน ฉันไม่ได้ใช้ jquery ect เพราะฉันต้องการให้โหลดทันทีที่เป็นไปได้


1

ใช้เวลาสองสามชั่วโมงในการทำความเข้าใจรายละเอียดทั้งหมดของปัญหานี้และหาวิธีการที่ดีที่สุด ปรากฎ ณ เดือนเมษายน 2559 มีเพียง iOS Chrome เท่านั้นที่มีปัญหานี้ ฉันลองใช้ Android Chrome และ iOS Safari แล้ว - ทั้งคู่ใช้ได้ดีโดยไม่มีการแก้ไขนี้ ดังนั้นการแก้ไขสำหรับ iOS Chrome ที่ฉันใช้คือ:

$(document).ready(function() {
   var screenHeight = $(window).height();
   $('div-with-background-image').css('height', screenHeight + 'px');
});

1

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

IE: ขนาดพื้นหลัง: 901px; สำหรับหน้าจอใด ๆ <900px ไม่สมบูรณ์หรือตอบสนอง แต่ทำงานได้ดีสำหรับฉันบนมือถือ <480px เหมือนฉันใช้ BG นามธรรม


0

ฉันใช้วิธีแก้ปัญหานี้: แก้ไขความสูงของ bg1 เมื่อโหลดหน้าเว็บโดย:

var BG = document.getElementById('bg1');
BG.style.height = BG.parentElement.clientHeight;

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

window.addEventListener("resize", onResize, false);
var BG = document.getElementById('bg1');
BG.style.height = BG.parentElement.clientHeight;
var oldH = BG.parentElement.clientHeight;

function onResize() {
    if(Math.abs(oldH - BG.parentElement.clientHeight) > 60){
      BG.style.height = BG.parentElement.clientHeight + 'px';
      oldH = BG.parentElement.clientHeight;
    }
}

PS: ข้อผิดพลาดนี้น่ารำคาญมาก!


0

คล้ายกับ @AlexKempton คำตอบ (ไม่สามารถแสดงความคิดเห็นขอโทษ)

ฉันใช้ความล่าช้าในการเปลี่ยนแปลงนานเพื่อป้องกันการปรับขนาดองค์ประกอบ

เช่น:

transition: height 250ms 600s; /*10min delay*/

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


0

สำหรับผู้ที่ต้องการฟังความสูงภายในที่แท้จริงและการเลื่อนในแนวตั้งของหน้าต่างในขณะที่เบราว์เซอร์มือถือ Chrome กำลังเปลี่ยนแถบ URL จากแสดงเป็นซ่อนและในทางกลับกันทางออกเดียวที่ฉันพบคือการตั้งค่าฟังก์ชันช่วงเวลาและ วัดความคลาดเคลื่อนของ window.innerHeightค่าก่อนหน้า

สิ่งนี้จะแนะนำรหัสนี้:

var innerHeight = window.innerHeight;
window.setInterval(function ()
{
  var newInnerHeight = window.innerHeight;
  if (newInnerHeight !== innerHeight)
  {
    var newScrollY = window.scrollY + newInnerHeight - innerHeight;
    // ... do whatever you want with this new scrollY
    innerHeight = newInnerHeight;
  }
}, 1000 / 60);

ฉันหวังว่ามันจะมีประโยชน์ ไม่มีใครรู้วิธีแก้ปัญหาที่ดีกว่า?


0

วิธีแก้ปัญหาที่ฉันเกิดขึ้นเมื่อมีปัญหาที่คล้ายกันคือการกำหนดความสูงขององค์ประกอบให้กับwindow.innerHeightทุกครั้งที่touchmoveเกิดเหตุการณ์

var lastHeight = '';

$(window).on('resize', function () {
    // remove height when normal resize event is fired and content redrawn
    if (lastHeight) {
        $('#bg1').height(lastHeight = '');
    }
}).on('touchmove', function () {
    // when window height changes adjust height of the div
    if (lastHeight != window.innerHeight) {
        $('#bg1').height(lastHeight = window.innerHeight);
    }
});

สิ่งนี้ทำให้องค์ประกอบครอบคลุม 100% ของหน้าจอที่มีอยู่ตลอดเวลาไม่มากและไม่น้อย แม้ในระหว่างแถบที่อยู่ซ่อนหรือแสดง

อย่างไรก็ตามมันเป็นเรื่องที่น่าเสียดายที่เราต้องหาแพทช์แบบposition: fixedนั้นมาใช้งาน


0

ด้วยการสนับสนุนคุณสมบัติที่กำหนดเอง CSS (ตัวแปร) ใน iOS คุณสามารถตั้งค่าเหล่านี้ด้วย JS และใช้พวกเขาบน iOS เท่านั้น

const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
if (iOS) {
  document.body.classList.add('ios');
  const vh = window.innerHeight / 100;
  document.documentElement.style
    .setProperty('--ios-10-vh', `${10 * vh}px`);
  document.documentElement.style
    .setProperty('--ios-50-vh', `${50 * vh}px`);
  document.documentElement.style
    .setProperty('--ios-100-vh', `${100 * vh}px`);
}
body.ios {
    .side-nav {
        top: var(--ios-50-vh);
    }
    section {
        min-height: var(--ios-100-vh);
        .container {
            position: relative;
            padding-top: var(--ios-10-vh);
            padding-bottom: var(--ios-10-vh);
        }
    }
}

0

คำตอบของฉันสำหรับทุกคนที่มาที่นี่ (เช่นฉัน) เพื่อค้นหาคำตอบสำหรับข้อผิดพลาดที่เกิดจากการซ่อนที่อยู่ / อินเตอร์เฟซเบราว์เซอร์

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

// Keep track of window width
let myWindowWidth = window.innerWidth;

window.addEventListener( 'resize', function(event) {

    // If width is the same, assume hiding address bar
    if( myWindowWidth == window.innerWidth ) {
         return;
    }

    // Update the window width
    myWindowWidth = window.innerWidth;

    // Do your thing
    // ...
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.