일반 CSS 부드러운 스크롤 "끝"

13440 단어 tutorialwebdevcss

This is the fourth post in a series examining modern CSS solutions to problems I've been solving over the last 13+ years of being a frontend developer. Visit ModernCSS.dev to view the whole series and additional resources.


이제 "복귀"링크는 자주 사용되지 않을 수도 있지만, 이 기술은 두 가지 현대 CSS 기능을 잘 보여 준다.
  • position: sticky
  • scroll-behavior: smooth
  • 나는 우선'귀환'링크를 사랑하게 되었고 2011년에 가장 화려한 사이트 중 하나Web Designer Wall에서 jQuery를 어떻게 사용하는지 배웠다.
    그 생각은 사용자에게'점프 링크'를 제공하여 사이트의 맨 위로 스크롤하는 것이다. 이것은 과거 블로그에서 자주 사용되었다.
    다음은 우리가 배울 내용입니다.

    위치 정보: 점성


    이 최신 위치 값은 caniuse 에 설명되어 있습니다.

    Keeps elements positioned as "fixed" or "relative" depending on how it appears in the viewport. As a result, the element is "stuck" when necessary while scrolling.


    caniuse 데이터의 또 다른 중요한 힌트는 최상의 지원을 위해 접두사를 제공해야 한다는 것입니다.우리의 프레젠테이션은 position: fixed로 되돌아갈 것이며, 이것은 약간 우아하지 않게 주요 목표를 실현할 것이다.

    스크롤 비헤이비어 정보: 부드럽게


    이것은 매우 새로운 속성이며 support is relatively low.이 정확한 정의는 스크롤 동작을 요구한다. 특히 닻 링크를 선택할 때 기본적이고 귀에 거슬리는 즉각적인 점프에 비해 매끄러운 애니메이션 외관을 가진다.
    이를 사용하면 점진적인 증강을 제공할 수 있다. 이것은 브라우저가 그것을 지원하는 사람들에게는 더욱 좋은 체험이 될 수 있지만, 그것을 지원하지 않는 브라우저에게도 적용된다는 것을 의미한다.
    놀랍게도 사파리는 이 점을 지원하는 데 뒤떨어졌지만 다른 주요 브라우저는 그렇다.

    설정 단계: 기본 내용 HTML


    우선, 우리는 기본 내용 형식에 대한 의미 표시를 설정해야 한다.
    <header id="top">Title</header>
    <main>
      <article>
        <!-- long form content here -->
      </article>
      <!-- Back to Top link -->
      <div class="back-to-top-wrapper">
        <a href="#top" class="back-to-top-link" aria-label="Scroll to Top">🔝</a>
      </div>
    </main>
    
    링크는 article 뒤에 있지만 main 안에 있습니다.이것은 본문의 구체적인 부분이 아니므로 우리는 그것이 초점 순서 중의 마지막이 되기를 바란다.
    또한 id="top"<header> 를 추가하고 이 앵커 포인트를 리셋 링크의 href 값으로 사용합니다.<main> 맨 위로 스크롤하고 싶으면 id를 이동하거나 페이지 맨 위에 있는 기존 id에 추가할 수 있습니다.

    부드러운 스크롤 추가


    우리의 목표의 첫 번째 부분은 다음과 같은 CSS 규칙을 통해 easy peasy입니다.
    /* Smooth scrolling IF user doesn't have a preference due to motion sensitivities */
    @media screen and (prefers-reduced-motion: no-preference) {
      html {
        scroll-behavior: smooth;
      }
    }
    
    h/t ~
    원본 솔루션이 고려되지 않음 지적prefers-reduced-motion이전에 나는 jQuery와 vanilla JS로 이것CSS-Tricks article에 책갈피를 추가했다.이 글은 이미 한동안 사용되었다. 새로운 방법이 사용될 때, 이 팀은 끊임없이 이런 글을 갱신하였는데, 이것은 우리로 하여금 매우 영광스럽게 한다👍
    나는 URL에 포함된 #anchor 페이지를 방문할 때, 그것은 여전히 매끄러운 스크롤을 실행하는데, 이것은 실제로 당신의 장면에 적합하지 않을 수도 있다는 이상한 점을 발견했다.

    '복귀'링크의 스타일을 설정합니다


    우리가 일을 시작하기 전에, 링크에 대해 기본적인 양식을 적용합시다.재미를 위해서 이모티콘을 사용했지만 스타일을 더 잘 제어하기 위해 SVG 아이콘으로 바꿀 수 있습니다.
    .back-to-top-link {
      display: inline-block;
      text-decoration: none;
      font-size: 2rem;
      line-height: 3rem;
      text-align: center;
      width: 3rem;
      height: 3rem;
      border-radius: 50%;
      background-color: #D6E3F0;
      /* emoji don't behave like regular fonts
         so this helped position it correctly */
      padding: 0.25rem;
    }
    
    이것은 우리에게 매우 기본적인 원형 단추를 주었다.전체 코드 펜에 "예쁘다"스타일과 :hover, :focus 스타일을 추가했지만 이것은 필요하지 않습니다.
    다음은 우리가 왜 이 링크에 포장기를 추가했는지 알고 싶을 수도 있습니다.기본적으로 스크롤 궤적을 만드는 링크를 만들어야 하기 때문이다.position: sticky의 설계 방식에 따라 DOM의 위치에서 요소를 추출합니다.그런 다음 Top 값을 존중하여 뷰포트를 기준으로 배치합니다.그러나, 우리는 링크를 문서의 끝에 놓을 것이다. 따라서 도움이 되지 않는다면, 링크는 기본적으로 영원히 추출되지 않을 것이다.
    우리는 페이지에서 더 높게 보일 수 있도록 포장기와 position: absolute 를 사용하여 링크의 위치를 변경할 것이다.브라우저는 시각적으로 조정된 위치(즉 뷰포트에 들어갈 때)를 사용하여 링크를 붙여넣을 시기를 계산합니다.
    따라서 우리의 포장 양식은 다음과 같다.
    /* How far of a scroll travel within <main> prior to the
       link appearing */
    $scrollLength: 100vh;
    
    .back-to-top-wrapper {
      // uncomment to visualize "track"
      // outline: 1px solid red;
      position: absolute;
      top: $scrollLength;
      right: 0.25rem;
      // Optional, extends the final link into the 
      // footer at the bottom of the page
      // Set to `0` to stop at the end of `main`
      bottom: -5em;
      // Required for best support in browsers not supporting `sticky`
      width: 3em;
      // Disable interaction with this element
      pointer-events: none;
    }
    
    마지막 정의는 당신에게 새로운 것일 수도 있습니다: pointer-events: none.이것은 본질적으로 클릭과 같은 상호작용 이벤트를 이 요소를 통과하게 하는 것이다. 그러면 문서의 나머지 부분을 막지 않을 것이다.예를 들어 우리는 이 포장기가 의외로 내용의 링크를 막는 것을 원하지 않는다.
    이 위치에서 링크가 초기 뷰포트 내용 아래에 약간 겹치는 것을 볼 수 있습니다.이러한 중첩을 방지하기 위해 <main> 에 양식을 추가하고 position: relative 절대 링크 패키지를 지정하는 데 가장 좋은 결과가 필요합니다.
    main {
      // leave room for the "scroll track"
      padding: 0 3rem;
      // required to make sure the `absolute` positioning of
      // the anchor wrapper is indeed `relative` to this element vs. the body
      position: relative;
      max-width: 50rem;
      margin: 2rem auto;
    
      // Optional, clears margin if last element is a block item 
      *:last-child {
        margin-bottom: 0;
      }
    }
    
    나머지는 링크에 다시 액세스하고 필요한 스타일을 추가하여 포지셔닝 작업을 전면적으로 전개하는 것입니다.
    .back-to-top-link {
      // `fixed` is fallback when `sticky` not supported
      position: fixed;
      // preferred positioning, requires prefixing for most support, and not supported on Safari
      // @link https://caniuse.com/#search=position%3A%20sticky
      position: sticky;
      // reinstate clicks
      pointer-events: all;
      // achieves desired positioning within the viewport
      // relative to the top of the viewport once `sticky` takes over, or always if `fixed` fallback is used
      top: calc(100vh - 5rem);
    
      // ... styles written earlier
    }
    
    fixed 반환은 sticky 포지셔닝이 지원되지 않는 브라우저에 링크가 항상 표시됩니다.지원sticky 시 링크가 $scrollLength 통과하기 전에 나타나지 않는 이상적인 효과가 발생합니다.sticky 위치를 사용하면 패키지의 위쪽이 뷰포트에 있으면 링크가 끊기고 사용자와 함께 스크롤됩니다.
    또한 링크의 상호 작용을 위해 pointer-events 값을 사용하여 all 을 복구했습니다.
    최종 결과입니다. - 비Safari에서 최상의 결과를 얻을 수 있습니다.

    이미 알고 있는 문제


    만약 비교적 짧은 폼 내용이 있다면, 비교적 짧은 장치 뷰포트에서 이것은 쉽게 실패하지 않을 것입니다.나처럼 사용하라고 생각할 수도 있다overflow: hidden.그러나 불행하게도 이로 인해 position: sticky 완전히 역할을 발휘하지 못했다☹️ 따라서'진실한 세계'장면에서 모든 문장의 이러한 행동을 전환하거나 문장을 템플릿에 주입하기 전에 계산을 해서 문장의 길이 요구를 충족시키는지 확인해야 할 수도 있습니다.
    만약 이 방법에 다른'결함'이 있다는 것을 알고 있거나 발견한다면 논평을 발표해 주십시오!

    좋은 웹페이지 즐겨찾기