Hoạt ảnh cuộn CSS thuần túy


76

Tôi đã tìm cách cuộn xuống khi nhấp vào nút nằm trên đầu trang chỉ sử dụng CSS3.

Vì vậy, tôi đã tìm thấy hướng dẫn này: http://tympanus.net/codrops/2012/06/12/css-only-responsive-layout-with-smooth-transitions/

Demo: http://tympanus.net/Tutorials/SmoothTransitionsResponsiveLayout/

Nhưng nó hơi quá cao so với nhu cầu của tôi vì tôi chỉ muốn trình duyệt cuộn xuống khi nhấp vào một nút nằm trên đầu trang, vì vậy tôi đã tự hỏi: liệu có thể thực hiện cuộn CSS đó mà không cần các nút đầu vào không, chỉ với một thẻ liên kết?

HTML trông như thế này: <a href="#" class="button">Learn more</a>

Tôi đã có một số CSS mà tôi cần kích hoạt khi nhấp vào nút:

/* Button animation tryout. */
.animate {
    animation: moveDown 0.6s ease-in-out 0.2s backwards;
}
@keyframes moveDown{
    0% { 
        transform: translateY(-40px); 
        opacity: 0;
    }
    100% { 
        transform: translateY(0px);  
        opacity: 1;
    }
}

7
Một nhược điểm lớn của cách cuộn dựa trên CSS này là người dùng không thể cuộn lên theo cách thủ công sau khi sử dụng tính năng cuộn dựa trên CSS đã cuộn xuống phần tử đã chọn. Có vẻ như người dùng sẽ trực giác muốn làm điều này, với sự chuyển đổi trang động! Đối với tôi, nó quay lại hoạt ảnh của jQuery ({scrollTop: ...}). Hay tôi đã bỏ lỡ điều gì đó?
vicmortelmans

1
Với giải pháp này, bạn có thể sửa lỗi không thể quay lại. Chỉ cần sử dụng đánh dấu HTML này: <div parallax="moveDown">...</div> Và nó sẽ di chuyển xuống khi bạn cuộn xuống và sao lưu khi bạn cuộn lên ...
elixon 13/02 '19

Câu trả lời:


89

Bạn có thể làm điều đó với các thẻ liên kết bằng cách sử dụng :targetcông cụ chọn giả css3 , công cụ chọn này sẽ được kích hoạt khi phần tử có cùng id với mã băm của URL hiện tại khớp. Thí dụ

Biết được điều này, chúng ta có thể kết hợp kỹ thuật này với việc sử dụng các bộ chọn vùng lân cận như "+" và "~" để chọn bất kỳ phần tử nào khác thông qua phần tử mục tiêu mà id khớp với băm của url hiện tại. Một ví dụ về điều này sẽ giống như những gì bạn đang hỏi .


5
Bạn có thể sử dụng kỹ thuật đích để nhắm mục tiêu bất kỳ phần tử nào trong bố cục, ngay cả chính trang chọn thẻ '<body>' :).
Jesus Bejarano,

2
nói, tại sao chúng ta cần backface-visibilitybản demo sau? chúng tôi không lật bất cứ thứ gì ...
Eliran Malka

17
Đối với bất cứ ai khác muốn nhìn thấy mức tối thiểu cần thiết cho hoạt hình này, tôi lấy ra định dạng vv để làm cho nó một chút dễ dàng hơn để làm việc ra những gì làm những gì jsfiddle.net/YYPKM/347
Louis Maddox

3
Như tôi cho rằng không thể linh hoạt ở đây, phải không? Việc chuyển đổi cần một giá trị thực và không thể được nhắm mục tiêu đến phần tử khác, phải không?
Keenora Fluffball

2
@LouisMaddox Thêm header { position: fixed; left: 0; top: 0; z-index: 10; }vào css của fiddle của bạn sẽ đảm bảo rằng các liên kết sẽ luôn có thể nhấp được, bởi vì ngay bây giờ, nhấp vào số 2 sẽ khiến số 1 không thể nhấp được.
Gellie Ann

116

Sử dụng các liên kết neo và thuộc scroll-behaviortính ( tham chiếu MDN ) cho vùng chứa cuộn:

scroll-behavior: smooth;

Hỗ trợ trình duyệt : Firefox 36+, Chrome 61+ (do đó cũng có Edge 79+) và Opera 48+.

Intenet Explorer, không phải Chromium Edge và (cho đến nay) Safari không hỗ trợ scroll-behaviorvà chỉ đơn giản là "nhảy" đến mục tiêu liên kết.

Ví dụ sử dụng:

<head>
  <style type="text/css">
    html {
      scroll-behavior: smooth;
    }
  </style>
</head>
<body id="body">
  <a href="#foo">Go to foo!</a>

  <!-- Some content -->

  <div id="foo">That's foo.</div>
  <a href="#body">Back to top</a>
</body>

Đây là một Fiddle .

Và đây cũng là một Fiddle với cả cuộn ngang và cuộn dọc.


9
Tại sao lại downvote? Bạn vui lòng giải thích cách tôi có thể cải thiện câu trả lời của mình hoặc tại sao giải pháp của tôi không tốt?
Felix Edelmann

1
Tôi thực sự chưa bao giờ nghĩ về việc cuộn ngang. Nhưng như bạn có thể thấy trong fiddle này: jsfiddle.net/1Lfybv56/2, nó cũng hoạt động - cũng với cả cuộn ngang và dọc. Điểm khác biệt duy nhất mà tôi phát hiện ra: Với tính năng cuộn ngang, liên kết neo đến thẻ name = "..." không hoạt động, bạn phải sử dụng id = "...".
Felix Edelmann

3
Bạn đang nhận được sự phản đối vì tại caniuse.com/#search=scroll-behavior, nó cho biết nó chỉ hoạt động trong firefox. Vì vậy, về cơ bản nó không có giá trị đối với các trang web cấp sản xuất vì nó chỉ hoạt động trong một trình duyệt thậm chí không được sử dụng nhiều nhất. BẤT NGỜ, lưu lượng truy cập trên trang web của bạn chủ yếu là firefox.
MeanMatt

2
Giải pháp của Jesus thực sự rất hay, nhưng tôi đang thêm vào câu trả lời của Felix vì nó hoạt động trong Chrome v62, Firefox v57 và đang được xem xét trong Edge (chưa hỗ trợ Safari) và chúng tôi muốn gây áp lực lên các nhà sản xuất trình duyệt. Vì vậy, đây là những gì tôi cung cấp cho sinh viên của mình như một ví dụ đơn giản cho các trình duyệt đó, cũng với các liên kết "hàng đầu" cuộn mượt mà: daveeveritt.github.io/css-smooth-scroll Kho lưu trữ ở đây có thêm thông tin và liên kết trong readme: github .com / DaveEveritt / css-mịn-scroll
Dave Everitt

1
Nó hoạt động trên tất cả các phiên bản Chrome và Firefox cực kỳ cổ điển, cũng như Trình duyệt Samsung. Trên tất cả các trang web của tôi, các phiên bản không được hỗ trợ của các trình duyệt này chiếm một phần thị phần không đáng kể khi tôi viết nhận xét này. Mối quan tâm ở đây chủ yếu là thiếu hỗ trợ trong Safari và ở một mức độ nào đó, IE và Edge. Tuy nhiên ... cho cách thanh lịch nó là gì và như thế nào đây là một tính năng không cần thiết, câu trả lời này có thể thu hút rất nhiều người dân (nó hấp dẫn đối với tôi vì lý do này.)
cazort

-2

Bạn có thể sử dụng tập lệnh của tôi từ CodePen bằng cách chỉ gói tất cả nội dung trong một DIV .levit-container.

~function  () {
    function Smooth () {
        this.$container = document.querySelector('.levit-container');
        this.$placeholder = document.createElement('div');
    }

    Smooth.prototype.init = function () {
        var instance = this;

        setContainer.call(instance);
        setPlaceholder.call(instance);
        bindEvents.call(instance);
    }

    function bindEvents () {
        window.addEventListener('scroll', handleScroll.bind(this), false);
    }

    function setContainer () {
        var style = this.$container.style;

        style.position = 'fixed';
        style.width = '100%';
        style.top = '0';
        style.left = '0';
        style.transition = '0.5s ease-out';
    }

    function setPlaceholder () {
        var instance = this,
                $container = instance.$container,
                $placeholder = instance.$placeholder;

        $placeholder.setAttribute('class', 'levit-placeholder');
        $placeholder.style.height = $container.offsetHeight + 'px';
        document.body.insertBefore($placeholder, $container);
    }

    function handleScroll () {
        this.$container.style.transform = 'translateZ(0) translateY(' + (window.scrollY * (- 1)) + 'px)';
    }

    var smooth = new Smooth();
    smooth.init();
}();

https://codepen.io/acauamontiel/pen/zxxebb?editors=0010


2
-1; câu hỏi yêu cầu một giải pháp chỉ CSS, nhưng câu trả lời của bạn hoàn toàn là JavaScript.
Mark Amery

-3

Và đối với các trình duyệt hỗ trợ webkit, tôi đã có kết quả tốt với:

.myElement {
    -webkit-overflow-scrolling: touch;
    scroll-behavior: smooth; // Added in from answer from Felix
    overflow-x: scroll;
}

Điều này làm cho hoạt động cuộn giống như hành vi trình duyệt tiêu chuẩn - ít nhất nó hoạt động tốt trên iPhone mà chúng tôi đang thử nghiệm!

Hy vọng rằng sẽ giúp,

Ed


3
Tôi đã đọc đặc tả MDN cho thuộc tính -webkit-tràn-cuộn và tôi nghĩ rằng nó chỉ thay đổi hành vi khi bạn thực hiện một cử chỉ cuộn. Người hỏi đã nghĩ đến việc cuộn tự động (vì vậy bạn chỉ nhấn vào một nút / liên kết và không phải vuốt xuống hoặc di chuyển các thanh cuộn) ;-). Nhân tiện, overflow-x: autotốt hơn trong hầu hết các trường hợp, vì nó chỉ hiển thị các thanh cuộn nếu thực sự có thứ gì đó để cuộn ( scrollsẽ luôn hiển thị các thanh).
Felix Edelmann
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.