모바일 브라우저에서 CSS3 100vh가 일정하지 않음 위로 이동하는 페이지를로드하면

매우 이상한 문제가 있습니다 … 모든 브라우저 및 모바일 버전 에서이 동작이 발생했습니다.

  • 페이지 스크롤을 시작할 때 위로 이동하는 페이지를로드하면 (예 : 주소 표시 줄 표시) 모든 브라우저에 최상위 메뉴가 있습니다.
  • 100vh는 때때로 뷰포트의 보이는 부분에서만 계산되므로 브라우저 막대가 100vh 위로 올라가면 픽셀 단위로 증가합니다
  • 치수가 변경되었으므로 모든 레이아웃을 다시 페인트하고 다시 조정
  • 사용자 경험에 좋지 않은 영향

이 문제를 어떻게 피할 수 있습니까? 내가 viewport-height에 대해 처음 들었을 때 나는 흥분했고 자바 스크립트를 사용하는 대신 고정 높이 블록에 사용할 수 있다고 생각했지만 실제로는 resize 이벤트가있는 실제로 javascript라고 생각합니다 …

샘플 사이트 에서 문제점을 볼 수 있습니다.

누구든지 CSS 솔루션을 제안 / 제안 할 수 있습니까?


간단한 테스트 코드 :



답변

불행히도 이것은 의도적 인 것입니다…

이것은 다른 문제를 방지하기 위해 의도적으로 알려진 잘 알려진 문제입니다 (적어도 사파리 모바일에서는). Benjamin Poulain이 웹킷 버그에 답했습니다 .

이것은 완전히 의도적 인 것입니다. 이 효과를 달성하기 위해서는 상당한 노력이 필요했습니다. 🙂

기본 문제는 이것입니다. 스크롤 할 때 보이는 영역이 동적으로 변경됩니다. CSS 뷰포트 높이를 적절히 업데이트하면 스크롤하는 동안 레이아웃을 업데이트해야합니다. 그것은 똥처럼 보일뿐만 아니라 60 FPS에서 그렇게하는 것은 대부분의 페이지에서 실제로 불가능합니다 (60 FPS는 iOS의 기본 프레임 속도입니다).

“똥 모양”부분을 보여주기는 어렵지만 스크롤 할 때 내용이 이동하고 화면에서 원하는 내용이 계속 바뀌고 있다고 상상해보십시오.

동적으로 높이를 업데이트하지 않으면 몇 가지 선택 사항이 있습니다 .iOS에서 뷰포트 단위를 삭제하고, iOS 8 이전과 같은 문서 크기를 일치시키고, 작은 뷰 크기를 사용하고, 큰 뷰 크기를 사용하십시오.

우리가 가진 데이터에서 더 큰 뷰 크기를 사용하는 것이 가장 타협했습니다. 뷰포트 단위를 사용하는 대부분의 웹 사이트는 대부분 멋지게 보였습니다.

Nicolas Hoizey는 이것을 꽤 연구했습니다 : https://nicolas-hoizey.com/2015/02/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile -browsers.html

수정 계획 없음

이 시점에서 모바일 장치에서 뷰포트 높이를 사용하지 않는 것 외에는 할 수있는 일이 많지 않습니다. 2016 년에도 Chrome이 다음과 같이 변경되었습니다.


답변

min-height: -webkit-fill-available;대신 CSS를 사용해보십시오 100vh. 해결되어야한다


답변

내 응용 프로그램에서 나는 그렇게합니다 (typescript 및 중첩 된 postcss, 따라서 코드를 적절하게 변경하십시오).

const appHeight = () => {
    const doc = document.documentElement
    doc.style.setProperty('--app-height', `${window.innerHeight}px`)
}
window.addEventListener('resize', appHeight)
appHeight()

당신의 CSS에서 :

:root {
   --app-height: 100%;
}

html,
body {
    padding: 0;
    margin: 0;
    overflow: hidden;
    width: 100vw;
    height: 100vh;

    @media not all and (hover:hover) {
        height: var(--app-height);
    }
}

그것은 적어도 크롬 모바일과 아이 패드에서 작동합니다. 작동하지 않는 것은 iOS의 홈 화면에 앱을 추가하고 방향을 몇 번 변경하면 확대 / 축소 수준이 innerHeight 값과 엉망이되어 해결책을 찾으면 업데이트를 게시 할 수 있습니다.

데모


답변

내가 구축 한 많은 사이트에 대해 클라이언트가 100vh 배너를 요청하고 찾은 것처럼 스크롤을 시작할 때 모바일에서 “점프”경험이 나빠집니다. 이것이 모든 장치에서 일관되고 일관된 경험을 위해 문제를 해결하는 방법입니다.

먼저 배너 요소 CSS를 height:100vh

그런 다음 jQuery를 사용하여 배너 요소의 높이를 픽셀 단위로 가져 오고이 높이를 사용하여 인라인 스타일을 적용합니다.

var viewportHeight = $('.banner').outerHeight();
$('.banner').css({ height: viewportHeight });

이렇게하면 페이지가로드 될 때 CSS를 사용하여 배너 요소가 100vh로 설정된 다음 모바일 요소의 문제가 해결됩니다 .jQuery는 배너 요소에 인라인 CSS를 배치하여 사용자가 스크롤하기 시작할 때 크기 조정을 중지하여이를 무시합니다.

그러나 데스크톱에서 사용자가 브라우저 창 크기를 조정하면 위의 jQuery로 인해 배너 요소의 높이가 고정되어 있기 때문에 배너 요소의 크기가 조정되지 않습니다. 이를 해결하기 위해 Mobile Detect 를 사용 하여 문서 본문에 ‘mobile’클래스를 추가합니다. 그런 다음 위의 jQuery를 if 문으로 묶습니다.

if ($('body').hasClass('mobile')) {
  var viewportHeight = $('.banner').outerHeight();
  $('.banner').css({ height: viewportHeight });
}

결과적으로 사용자가 모바일 장치에 있으면 클래스 ‘mobile’이 내 페이지 본문에 있으며 위의 jQuery가 실행됩니다. 따라서 내 배너 요소는 모바일 장치에 적용된 인라인 CSS 만 가져 오는 반면 데스크톱에서는 원래 100vh CSS 규칙이 그대로 유지됩니다.


답변

이 답변을보십시오 : https://css-tricks.com/the-trick-to-viewport-units-on-mobile/

// First we get the viewport height and we multiple it by 1% to get a value for a vh unit
let vh = window.innerHeight * 0.01;
// Then we set the value in the --vh custom property to the root of the document
document.documentElement.style.setProperty('--vh', `${vh}px`);

// We listen to the resize event
window.addEventListener('resize', () => {
  // We execute the same script as before
  let vh = window.innerHeight * 0.01;
  document.documentElement.style.setProperty('--vh', `${vh}px`);
});
body {
  background-color: #333;
}

.module {
  height: 100vh; /* Use vh as a fallback for browsers that do not support Custom Properties */
  height: calc(var(--vh, 1vh) * 100);
  margin: 0 auto;
  max-width: 30%;
}

.module__item {
  align-items: center;
  display: flex;
  height: 20%;
  justify-content: center;
}

.module__item:nth-child(odd) {
  background-color: #fff;
  color: #F73859;
}

.module__item:nth-child(even) {
  background-color: #F73859;
  color: #F1D08A;
}
<div class="module">
  <div class="module__item">20%</div>
  <div class="module__item">40%</div>
  <div class="module__item">60%</div>
  <div class="module__item">80%</div>
  <div class="module__item">100%</div>
</div>


답변

React 구성 요소를 생각해 냈습니다. React 를 사용하거나 소스 코드를 탐색 하는지 확인하십시오. 그렇지 않은 경우 하여 환경에 맞게 조정할 수 있습니다.

전체 화면 div의 높이를 window.innerHeight 다음 창 크기 조정시 업데이트합니다.


답변

며칠 동안 해결책을 찾고 있었으므로 VueJS를 Vuetify와 함께 사용하는 모든 사람들을위한 광산입니다 (내 솔루션은 v-app-bar, v-navigation-drawer 및 v-footer를 사용합니다) : App.scss를 만들었습니다 (App에서 사용). vue) 다음 내용이 포함됩니다.

.v-application {
    height: 100vh;
    height: -webkit-fill-available;
}

.v-application--wrap {
    min-height: 100vh !important;
    min-height: -webkit-fill-available !important;
}