Đã sửa lỗi chồng chéo tiêu đề trang trong trang neo


358

Nếu tôi có một tiêu đề không cuộn trong trang HTML, được cố định ở trên cùng, có chiều cao được xác định:

Có cách nào để sử dụng neo URL ( #fragmentphần) để trình duyệt cuộn đến một điểm nhất định trong trang, nhưng vẫn tôn trọng chiều cao của phần tử cố định mà không cần sự trợ giúp của JavaScript không?

http://foo.com/#bar
SAI (nhưng hành vi phổ biến): ĐÚNG:
+ --------------------------------- + + -------------- ------------------- +
| BAR /////////////////////// tiêu đề | | ////////////////////////// tiêu đề |
+ --------------------------------- + + -------------- ------------------- +
| Đây là phần còn lại của Văn bản | | THANH |
| ... | | |
| ... | | Đây là phần còn lại của Văn bản |
| ... | | ... |
+ --------------------------------- + + -------------- ------------------- +



3
@ax CÓ, đó là câu trả lời tốt nhất. Đồng thời kiểm tra nicolasgallagher.com/jump-links-and-viewport-poseitioning/demo bên trong nó. Điều này làm việc tốt nhất với tôi:.dislocate50px, #bar { padding: 50px 0 0; margin: -50px 0 0; -webkit-background-clip: content-box; background-clip: content-box; }
flen

Tôi đang tìm kiếm một giải pháp * hoạt động cho các neo đến từ cùng một trang hoặc trang khác, * và điều chỉnh nhấn phím xuống để nội dung không bị cắt bởi tiêu đề, * và cho phép chân trang sib-div cuộn lên với nội dung-div. Chưa tìm được giải pháp! Nhưng tôi phải nói rằng, tôi nghĩ rằng cách đúng đắn sẽ nhắm mục tiêu toàn bộ div nội dung chứ không phải từng neo riêng lẻ. stackoverflow.com/questions/51070758/
Mạnh

@cây rìu. CSS-tricks.com có ​​một bài viết mới hơn tốt hơn về scroll-padding-topđây: css-tricks.com/ Từ Câu trả lời tương ứng: stackoverflow.com/a/56467997/247696
Flimm

Câu trả lời:


167

Tôi đã từng gặp vấn đề tương tự. Tôi đã giải quyết nó bằng cách thêm một lớp vào phần tử neo với chiều cao thanh trên cùng làm giá trị padding-top.

<h1><a class="anchor" name="barlink">Bar</a></h1>

Và sau đó chỉ đơn giản là css:

.anchor { padding-top: 90px; }

19
@Tomalak Hãy lưu ý rằng giải pháp này làm cho các liên kết bên trong khu vực đệm không thể nhấp được. Để khắc phục điều này, bạn phải sử dụng chỉ mục z và đặt giá trị liên kết cao hơn giá trị neo. Hãy nhớ rằng thanh trên cùng của bạn phải có giá trị chỉ mục z cao nhất, vì vậy nội dung của trang không nổi trên thanh trên cùng khi bạn cuộn.
MutttenXd

Không hoạt động trong Chrome v28 do lỗi vị trí cố định WebKit khiến tiêu đề biến mất. Câu trả lời này đã lừa tôi trường hợp của tôi.
Knickyi

2
MuttenXd .. bạn là anh hùng của tôi. Tôi có vấn đề liên kết phi chức năng kỳ lạ trên trang web của tôi (không liên quan đến neo) đã khiến tôi phát điên. Nhận xét không thể nhấp của bạn thực sự có ích. Tôi nợ bạn lớn!
zipzit

9
Như được đề xuất trong câu trả lời của Roy Shoa, hãy thêm margin-top: -90px;vào để chống lại khoảng trống được tạo ra bởi phần đệm.
Skippy le Grand Gourou

37
Tôi đã sử dụng .anchor:target {padding-top: 90px;}để nó chỉ thêm phần đệm khi họ sử dụng thẻ neo. Bằng cách này, không phải lúc nào cũng có một loạt các phần đệm nếu trang tải ở đầu trang. Chỉ khi nó tải một điểm cụ thể thấp hơn trên trang.
jimmyplaysdrums

265

Nếu bạn không thể hoặc không muốn thiết lập một lớp mới, hãy thêm một ::beforephần tử giả có chiều cao cố định vào lớp :targetgiả trong CSS:

:target::before {
  content: "";
  display: block;
  height: 60px; /* fixed header height*/
  margin: -60px 0 0; /* negative fixed header height */
}

Hoặc cuộn trang tương đối :targetvới jQuery:

var offset = $(':target').offset();
var scrollto = offset.top - 60; // minus fixed header height
$('html, body').animate({scrollTop:scrollto}, 0);

30
Tôi thực sự thích giải pháp của bạn. Đó là giải pháp sạch nhất tôi tìm thấy.
Itay Grudev

5
Đây là giải pháp hoạt động hoàn hảo cho tôi mà không nhồi nhét bất cứ thứ gì khác vào bố cục trang của tôi.
Jamie Carl

2
Giải pháp CSS có vấn đề khi được sử dụng với danh sách trong WebKit. Nhìn: stackoverflow.com/questions/39547773/
Mạnh

14
Nó sẽ không hoạt động nếu mục tiêu có phần đệm hoặc đường viền trên cùng vì nó phụ thuộc vào sự sụp đổ lề.
krulik

9
:targetRực rỡ!
Vô tận

125

Tôi sử dụng phương pháp này:

/* add class="jumptarget" to all targets. */

.jumptarget::before {
  content:"";
  display:block;
  height:50px; /* fixed header height*/
  margin:-50px 0 0; /* negative fixed header height */
}

Nó thêm một yếu tố vô hình trước mỗi mục tiêu. Nó hoạt động IE8 +.

Dưới đây là nhiều giải pháp: http://nicolasgallagher.com/jump-links-and-viewport-poseitioning/


nhìn vào liên kết Badabam cung cấp, có một giải pháp thứ hai mà tôi sử dụng và nó hoạt động trong Chrome và Firefox
người quét rác

Đã thử nghiệm điều này trên Firefox mới nhất (55.0.3 trên PC) và nó hoạt động ngay bây giờ. :-)
RachieVee

46

Bootstrap chính thức thông qua Trả lời:

*[id]:before { 
  display: block; 
  content: " "; 
  margin-top: -75px; // Set the Appropriate Height
  height: 75px; // Set the Appropriate Height
  visibility: hidden; 
}

Tín dụng

Hợp nhất


1
Cảm ơn rất nhiều vì đã bao gồm điều này, +1 cho sự hoàn chỉnh.
amjoconn

2
Giải pháp này có vấn đề khi được sử dụng với danh sách trong WebKit. Nhìn: stackoverflow.com/questions/39547773/
Mạnh

Lưu ý rằng điều này sẽ không hoạt động nếu chính phần tử đích xảy ra có display: flex;hoặc padding-top. Sử dụng một yếu tố neo chuyên dụng (như <a name="my_link">{leave this empty}</a>) trong những trường hợp đó.
WoodrowShigeru

Điều này sẽ không hoạt động nếu yếu tố mục tiêu là <tr>
Ivan Gusev

42
html {
  scroll-padding-top: 70px; /* height of sticky header */
}

từ: https://css-tricks.com/fixed-headers-on-page-links-and-overlaps-content-oh-my/



Làm việc cho tôi. Tôi đang điều hướng đến mỏ neo từ một trang khác. Những người khác đã không làm việc. Cảm ơn!
davidloper

1
Điều này không hoạt động để cuộn toàn bộ trang trong Edge và Safari ( bug.webkit.org/show_orms.cgi?id=179379 ).
Juliusz Gonera

1
Cứu tinh! Đơn giản, về điểm. Không có giải pháp nào khác phù hợp với tôi vì tôi đang sử dụng display: flex. Cảm ơn rất nhiều, thật là bực bội khi thử tất cả các giải pháp.
Priya Payyavula

Đây là một giải pháp ĐAP, tôi đã sử dụng hành vi cuộn: trơn tru! Quan trọng; cũng để đi neo, thực sự đơn giản trong hai dòng mã
yehanny

30

Cách tốt nhất mà tôi tìm thấy để xử lý vấn đề này là (thay thế 65px bằng chiều cao phần tử cố định của bạn):

div:target {
  padding-top: 65px; 
  margin-top: -65px;
}

Nếu bạn không thích sử dụng bộ chọn mục tiêu, bạn cũng có thể thực hiện theo cách này:

.my-target {
    padding-top: 65px;
    margin-top: -65px;
}

Lưu ý: ví dụ này sẽ không hoạt động nếu phần tử đích có màu nền khác với cha mẹ của nó. ví dụ:

<div style="background-color:red;height:100px;"></div>
<div class="my-target" style="background-color:green;height:100px;"></div>

trong trường hợp này, màu xanh lục của phần tử my-target sẽ ghi đè lên phần tử màu đỏ cha mẹ của anh ta trong 65px. Tôi không tìm thấy bất kỳ giải pháp CSS thuần túy nào để xử lý vấn đề này nhưng nếu bạn không có màu nền khác thì giải pháp này là tốt nhất.


2
Trong số tất cả các câu trả lời, đây là người duy nhất đã làm việc cho tôi!
Javier Arias

18

Mặc dù một số giải pháp được đề xuất hoạt động cho các liên kết phân đoạn (= liên kết băm) trong cùng một trang (như liên kết trình đơn cuộn xuống), tôi thấy rằng không có giải pháp nào trong số chúng hoạt động trong Chrome hiện tại khi bạn muốn sử dụng các liên kết phân đoạn đến từ khác trang .

Vì vậy, việc gọi www.mydomain.com/page.html#foo từ đầu sẽ KHÔNG bù mục tiêu của bạn trong Chrome hiện tại bằng bất kỳ giải pháp CSS hoặc giải pháp JS đã cho nào.

Ngoài ra còn có một báo cáo lỗi jQuery mô tả một số chi tiết của vấn đề.

GIẢI PHÁP

Tùy chọn duy nhất tôi tìm thấy cho đến nay thực sự hoạt động trong Chrome là JavaScript không được gọi là onDomReady nhưng có độ trễ.

// set timeout onDomReady
$(function() {
    setTimeout(delayedFragmentTargetOffset, 500);
});

// add scroll offset to fragment target (if there is one)
function delayedFragmentTargetOffset(){
    var offset = $(':target').offset();
    if(offset){
        var scrollto = offset.top - 95; // minus fixed header height
        $('html, body').animate({scrollTop:scrollto}, 0);
    }
}

TÓM LƯỢC

Nếu không có giải pháp trì hoãn JS có thể sẽ hoạt động trong Firefox, IE, Safari, nhưng không phải trong Chrome.


3
Tôi đã đi đến kết luận và giải pháp tương tự. Có vẻ như mọi người khác đều quên mất các liên kết bên ngoài sử dụng hashtags.
AJJ

Tôi có vấn đề đó ngày hôm nay và tôi đã sử dụng giải pháp của bạn. Mặc dù có vẻ như bạn không cần thời gian chờ. Điều này cũng hoạt động như IIFE.
kwiat1990

1
@ kwiat1990: Có, điều đó có thể là có thể - nhưng chỉ khi mã JS của bạn được đặt ở cuối mã HTML. Nếu không, mục tiêu cuộn của bạn có thể chưa có trong DOM. Trên thực tế đó là toàn bộ quan điểm của việc sử dụng onDomReady. Vì vậy, tôi đoán phiên bản hết thời gian là cách ổn định để đi.
Jpsy

Câu trả lời này là người duy nhất làm việc cho các liên kết bên ngoài. Tuy nhiên nó không hoạt động với tôi khi liên kết được gọi trong cùng một trang :( Có ý tưởng nào không?
Augusto Samamé Barrientos

@Augusto bạn đã tìm ra giải pháp chưa? Tôi đang có cùng một vấn đề.
Jesse

9

Khi CSS Scroll Snap xuất hiện trong trò chơi, có thể dễ dàng với thuộc scroll-margin-toptính. Hiện đang chạy trên Chrome và Opera (tháng 4 năm 2019). Ngoài ra Safari 11+ cũng hỗ trợ điều này, nhưng tôi không thể chạy nó trên Safari 11. Có lẽ chúng ta phải chờ đợi mọi người sửa nó.

Ví dụ Codepen

body {
  padding: 0;
  margin: 0;
}

h1,
p {
  max-width: 40rem;
  margin-left: auto;
  margin-right: auto;
}
h1 {
  scroll-margin-top: 6rem; /* One line solution. :-) */
}
.header {
  position: sticky;
  top: 0;
  background-color: red;
  text-align: center;
  padding: 1rem;
}
.header .scroll {
  display: block;
  color: white;
  margin-bottom: 0.5rem;
}
.header .browsers {
  color: black;
  font-size: 0.8em;
}
<header class="header">
  <a class="scroll" href="#heading">Scroll to heading</a>
  <span class="browsers" >Chrome 69+, Opera 56+ and Safari 11+ only</span>
</header>
<p>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<h1 id="heading">What is Lorem Ipsum?</h1>
<p>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<p>
  

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent pulvinar eleifend dolor, in cursus augue interdum quis. Morbi volutpat pulvinar nisl et condimentum. Quisque elit lacus, egestas non ante sit amet, hendrerit commodo dui. Nunc ac sagittis dolor. Proin iaculis ante non est pharetra, et ullamcorper nisl accumsan. Aenean quis leo vel sapien eleifend aliquam. Pellentesque finibus dui ex, blandit tristique risus vestibulum vitae. Nam a quam ac turpis porta eleifend. Sed at hendrerit risus, ac efficitur ante. Aenean pretium justo feugiat condimentum consectetur. Etiam mattis urna id porta hendrerit.
</p>
<p>
Mauris venenatis quam sed egestas auctor. Fusce lacus eros, condimentum nec quam vel, malesuada gravida libero. Praesent vel sollicitudin justo. Donec mattis nisl id mauris scelerisque, quis placerat lectus scelerisque. Ut id justo a magna mattis luctus. Suspendisse massa est, pretium vel suscipit sit amet, iaculis at mi. Aenean vulputate ipsum non consectetur sodales. Proin aliquet erat nec mi eleifend, eu dapibus enim ultrices. Sed fringilla tortor ac rhoncus consectetur. Aliquam aliquam orci ultrices tortor bibendum facilisis.
</p>
<p>
Donec ultrices diam quam, non tincidunt purus scelerisque aliquam. Nam pretium interdum lacinia. Donec sit amet diam odio. Donec eleifend nibh ut arcu dictum, in vulputate magna malesuada. Nam id dignissim tortor. Suspendisse commodo, nunc sit amet blandit laoreet, turpis nibh rhoncus mi, et finibus nisi diam sed erat. Vivamus diam arcu, placerat in ultrices eu, porta ut tellus. Aliquam vel nisi nisi.
</p>
<p>
Integer ornare finibus sem, eget vulputate lacus ultrices ac. Vivamus aliquam arcu sit amet urna facilisis consectetur. Sed molestie dolor et tortor elementum, nec bibendum tortor cursus. Nulla ipsum nulla, luctus nec fringilla id, sagittis et sem. Etiam at dolor in libero pharetra consequat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse quis turpis non diam mattis varius. Praesent at gravida mi. Etiam suscipit blandit dolor, nec convallis lectus mattis vitae. Mauris placerat erat ipsum, vitae interdum mauris consequat quis. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
<p>
Nunc efficitur scelerisque elit. Integer ac massa ipsum. Cras volutpat nulla purus, quis molestie dolor iaculis eget. Maecenas ut ex nulla. Pellentesque sem augue, ornare ut arcu eu, porttitor consectetur orci. Aenean iaculis blandit quam, in efficitur justo sodales auctor. Vivamus dignissim pellentesque risus eget consequat. Pellentesque sit amet nisi in urna convallis egestas vitae nec mauris. 
</p>


1
Điều đó thật ngọt ngào. Hãy hy vọng nó sẽ được chấp nhận rộng rãi hơn!
Tomalak

Sự khác biệt giữa scroll-padding-topvà là scroll-margin-topgì?
Flimm

scroll-margin-topđối với trường hợp sử dụng này, không may không được triển khai trong Safari 11-13: bug.webkit.org/show_orms.cgi?id=189265
fabb

Trong Safari, nó được gọi là scroll-snap-margin-top: caniuse.com/#search=scroll-margin-top
Mu-Tsun Tsai

@ Mu-TsunTsai Nó phức tạp hơn một chút. Điều này thực sự tồn tại trên Safari, nhưng nó không hoạt động với hành vi cuộn sang mảnh. Xem bình luận của tôi trong vấn đề dữ liệu trình duyệt: github.com/mdn/browser-compat-data/issues/ chủ
dakur

8

Đối với Chrome / Safari / Firefox, bạn có thể thêm display: blockvà sử dụng lề âm để bù vào phần bù, như:

a[name] {
    display: block;
    padding-top: 90px;
    margin-top: -90px;
}

Xem ví dụ http://codepen.io/swed/pen/RrZBJo


7

Bạn có thể làm điều này với jQuery:

var offset = $('.target').offset();
var scrollto = offset.top - 50; // fixed_top_bar_height = 50px
$('html, body').animate({scrollTop:scrollto}, 0);

Không phải ".target", nên là ": target"
Mert S. Kaplan

@ MertS.Kaplan ".target" là lớp 'mục tiêu'.
webvitaly

7

Chỉ cần phát hiện ra một giải pháp CSS thuần túy khác có tác dụng như một cơ duyên đối với tôi!

html {
  scroll-padding-top: 80px; /* height of your sticky header */
}

Tìm thấy trên trang web này !


2
Một vài người khác đã phát hiện ra giải pháp này trước bạn, xem câu trả lời trên trang 1, ví dụ stackoverflow.com/a/56467997/18771
Tomalak

Xin lỗi, không để ý! Cảm ơn!
jamawe

Điều này không hoạt động để cuộn toàn bộ trang trong Edge và Safari ( bug.webkit.org/show_orms.cgi?id=179379 ).
Juliusz Gonera

5

Bạn có thể thử điều này:

<style>
h1:target { padding-top: 50px; }
</style>

<a href="#bar">Go to bar</a>

<h1 id="bar">Bar</h1>

Đặt giá trị đệm hàng đầu cho chiều cao thực tế của tiêu đề của bạn. Điều này sẽ giới thiệu một khoảng trống nhỏ ở đầu tiêu đề của bạn, nhưng nó sẽ chỉ hiển thị khi người dùng nhảy đến neo và sau đó cuộn lên. Tôi đã tạo ra giải pháp đó cho trang web của mình ngay bây giờ, nhưng nó chỉ hiển thị một thanh cố định nhỏ ở đầu trang, không có gì quá cao.


Ừm Không tệ, nhưng vẫn khá hack (và không hoạt động trong IE, thật đáng buồn).
Tomalak

5

Tôi đã làm cho nó hoạt động dễ dàng với CSS và HTML, sử dụng phương thức "anchor: before" được đề cập ở trên. Tôi nghĩ rằng nó hoạt động tốt nhất, bởi vì nó không tạo ra phần đệm lớn giữa các div của bạn.

.anchor:before {
  content:"";
  display:block;
  height:60px; /* fixed header height*/
  margin:-60px 0 0; /* negative fixed header height */
}

Nó dường như không hoạt động cho div đầu tiên trên trang, nhưng bạn có thể chống lại điều đó bằng cách thêm phần đệm vào div đầu tiên đó.

#anchor-one{padding-top: 60px;}

Đây là một câu đố làm việc: http://jsfiddle.net/FRpHE/24/


5

Nó hoạt động với tôi:

Liên kết HTML đến Neo:

<a href="#security">SECURITY</a>

Neo HTML:

<a name="security" class="anchor"></a>

CSS:

.anchor::before {
    content: "";
    display: block;
    margin-top: -50px;
    position: absolute;
}

4

Tôi đang sử dụng câu trả lời của @ Jpsy, nhưng vì lý do hiệu suất, tôi chỉ đặt bộ hẹn giờ nếu hàm băm có trong URL.

$(function() {
      // Only set the timer if you have a hash
      if(window.location.hash) {
        setTimeout(delayedFragmentTargetOffset, 500);
      }
  });

function delayedFragmentTargetOffset(){
      var offset = $(':target').offset();
      if(offset){
          var scrollto = offset.top - 80; // minus fixed header height
          $('html, body').animate({scrollTop:scrollto}, 0);
          $(':target').highlight();
      }
  };

OP yêu cầu không sử dụng javascript.
Giulio Caccin

Hoạt động với các liên kết bên ngoài nhưng không phải với các liên kết trong trang.
chụp

4

Tôi đã gặp nhiều rắc rối với nhiều câu trả lời ở đây và những nơi khác vì các neo được đánh dấu của tôi là phần tiêu đề trong trang Câu hỏi thường gặp, vì vậy việc bù đắp tiêu đề không giúp ích gì vì phần còn lại của nội dung sẽ chỉ ở vị trí đó. Vì vậy, tôi nghĩ rằng tôi sẽ đăng.

Điều cuối cùng tôi làm là tổng hợp một vài giải pháp:

  1. CSS:

    .bookmark {
        margin-top:-120px;
        padding-bottom:120px; 
        display:block;
    }

Trong đó "120px" là chiều cao tiêu đề cố định của bạn (có thể cộng với một số lề).

  1. Liên kết đánh dấu HTML:

    <a href="#01">What is your FAQ question again?</a>
  2. Nội dung được đánh dấu HTML:

    <span class="bookmark" id="01"></span>
    <h3>What is your FAQ question again?</h3>
    <p>Some FAQ text, followed by ...</p>
    <p>... some more FAQ text, etc ...</p>

Điểm hay của giải pháp này là spanyếu tố không chỉ bị ẩn mà về cơ bản nó bị sụp đổ và không làm mất đi nội dung của bạn.

Tôi không thể tin tưởng nhiều vào giải pháp này vì nó đến từ một loạt các tài nguyên khác nhau, nhưng nó hoạt động tốt nhất với tôi trong tình huống của tôi.

Bạn có thể xem kết quả thực tế ở đây .


1
Cảm ơn bạn rất nhiều vì đã chia sẻ! Chủ đề cũ, dường như vẫn chưa có một giải pháp kinh điển nào cho vấn đề này.
Tomalak

1
+ SteveCinq Bạn đọc suy nghĩ của tôi - Tôi đã phải đối mặt với những vấn đề tương tự khi các giải pháp được chia sẻ không hoạt động như dự đoán. Thêm vào <span>với neo trong nhịp, cùng với việc thêm vào phần đệm và lề làm việc cho tôi. Cảm ơn rất nhiều vì đã dành thời gian để gửi câu trả lời này bất chấp tuổi của chủ đề!
twknab

4

Tôi đã không gặp may mắn với câu trả lời được liệt kê ở trên và cuối cùng đã sử dụng giải pháp này hoạt động hoàn hảo ...

Tạo một khoảng trống nơi bạn muốn đặt neo của mình.

<span class="anchor" id="section1"></span>
<div class="section"></div>

Và áp dụng lớp sau:

.anchor {
  display: block;
  height: 115px;       /* same height as header */
  margin-top: -115px;  /* same height as header */
  visibility: hidden;
}

Giải pháp này sẽ hoạt động ngay cả khi các phần có nền màu khác nhau! Tôi tìm thấy giải pháp tại liên kết này.


1
Đó không phải là chính xác cùng một phương pháp mà Guillaume Le Mière và một vài người khác đã thể hiện trong chủ đề này sao?
Tomalak

Nó rất giống nhau nhưng tôi nghĩ nó dễ hiểu hơn và phản hồi chi tiết hơn với một liên kết sâu hơn nữa đến một nguồn bên ngoài.
Matt Underwood

Đó là cùng một giải pháp, nhưng tôi có thể hiểu và làm theo cách này một cách dễ dàng. Những người khác đã không cung cấp cho tôi đủ thông tin.
MacroMan

3

Tôi cảm thấy hơi khó chịu với đầu óc thuần túy của mình nhưng là một giải pháp chỉ dành cho css, bạn có thể thêm phần đệm vào phần tử neo hoạt động bằng cách sử dụng :targetbộ chọn:

html, body {height:100%; min-height:100%; margin:0;}
body {min-height:200%;}
header {display:inline-block; position:fixed; font-size:1.5em; height:100px; top:0; left:0; right:0; line-height:100px; background:black; text-align:center;}
header a {color:#fff;}
section {padding:30px; margin:20px;}
section:first-of-type, section:target {padding-top:130px;}
<header><a href="#one">#One</a> <a href="#two">#two</a> <a href="#three">#three</a></header>
<section id="one"><h1>One</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>
<section id="two"><h1>Two</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>
<section id="three"><h1>Three</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>


1
Đó không phải là hacky! Giải pháp tốt đẹp.
Tomalak

3

Tôi tìm thấy tôi đã phải sử dụng cả hai MutttenXd 's và Badabam ' giải pháp CSS s với nhau, như làm đầu tiên không làm việc trong Chrome và lần thứ hai không làm việc trong Firefox:

a.anchor { 
  padding-top: 90px;
}

a.anchor:before { 
  display: block;
  content: "";
  height: 90px;
  margin-top: -90px;
}

<a class="anchor" name="shipping"></a><h2>Shipping (United States)</h2>
...

3

Cách mà tôi thấy là sạch nhất là cách sau:

  #bar::before {
    display: block;
    content: " ";
    margin-top: -150px;
    height: 150px;
    visibility: hidden;
    pointer-events: none;
  }

2

Một cách tiếp cận xâm nhập tối thiểu bằng jQuery:

Liên kết:

<a href="#my-anchor-1" class="anchor-link">Go To Anchor 1</a>

Nội dung:

<h3 id="my-anchor-1">Here is Anchor 1</a>

Kịch bản:

$(".anchor-link").click(function() {
    var headerHeight = 120;
    $('html, body').stop(true, true).animate({
        scrollTop: $(this.hash).offset().top - headerHeight
    }, 750);
    return false;
});

Bằng cách gán lớp liên kết neo cho các liên kết, hành vi của các liên kết khác (như accordion hoặc điều khiển tab) không bị ảnh hưởng.

Câu hỏi không muốn javascript nhưng câu hỏi phổ biến khác đã bị đóng vì câu hỏi này và tôi không thể trả lời ở đó.


2

Tôi cần một cái gì đó hoạt động cho các liên kết trong, liên kết trên trang, VÀ có thể được nhắm mục tiêu bởi JS để trang có thể đáp ứng với các thay đổi về chiều cao tiêu đề

HTML

<ul>
  <li><a href="#ft_who">Who?</a></li>
  <li><a href="#ft_what">What?</a></li>
  <li><a href="#ft_when">When?</a></li>
</ul>
...
<h2 id="ft_who" class="fragment-target">Who?</h2> 
...
<a href="#">Can I be clicked?</a>
<h2 id="ft_what" class="fragment-target">What?</h2>
...
<h2 id="ft_when" class="fragment-target">When?</h2> 

CSS

.fragment-target {
    display: block;
    margin-top: -HEADER_HEIGHTpx;
    padding-top: HEADER_HEIGHTpx;
    z-index: -1;
}

Các z-index: -1phép liên kết trong 'vùng đệm' ở trên một mảnh mục tiêu vẫn có thể nhấp vào, như nhận xét của @MuttenXd về câu trả lời của mình

Tôi chưa tìm thấy sự cố nào trong IE 11, Edge 15+, Chrome 38+, FF 52+ hoặc Safari 9.1+


1
<div style="position:relative; top:-45px;">
    <a name="fragment"> </a>
</div>

Mã này nên thực hiện các mẹo. Trao đổi 45px cho chiều cao của thanh tiêu đề của bạn.

EDIT: Nếu sử dụng jQuery là một tùy chọn, tôi cũng đã thành công khi sử dụng jQuery.localScroll với một bộ giá trị bù. Tùy chọn offset là một phần của jQuery.scrollTo, mà jQuery.localScroll được xây dựng dựa trên. Một bản demo có sẵn ở đây: http://demos.flesler.com/jquery/scrollTo/ (cửa sổ thứ hai, dưới 'offset')


Giải pháp này thực sự hiệu quả, nhưng nó không chống đạn và nó đòi hỏi rất nhiều khả năng hoàn thiện cho các trình duyệt khác nhau :( thử tốt. Tôi đang tìm kiếm một giải pháp mà không cần đánh dấu thêm.
vlad saling

Thật xấu hổ vì điều này rất lộn xộn, có nghĩa là bạn không thể chỉ sử dụng ID. Rất thích tìm một giải pháp, tôi đã thử tất cả mọi thứ.
lý thuyết

1

Đây là một giải pháp jquery hoàn chỉnh sẽ hoạt động trong IE:

Giả sử các thành phần thanh điều hướng là một cái gì đó như thế này:

<ul>
    <li><a class="navigation" href="/#contact-us">Contact us</a></li>
    <li><a class="navigation" href="/#about-us">About us</a></li>
</ul>

Bạn có thể sử dụng đoạn trích jquery sau để bù cuộn:

$(function() {
    $("a.navigation").click(function(event) {
        event.preventDefault();
        offSetScroll($(this));
    });
    offSetScrollFromLocation(window.location.href.toLowerCase());
});

function offSetScroll(anchor) {
    var href = anchor.attr("href");
    offSetScrollFromLocation(href);
}

function offSetScrollFromLocation(href) {
    //Change this according to the height of the navigation bar
    var fromTop = 250;
    if(href.indexOf("#")<=0)
        return;
    var hash=href.substring(href.indexOf("#"));
    var targetOffset = $(hash).offset().top-fromTop;
    $('html, body').animate({scrollTop: targetOffset}, 400, function(e) {

    });
}

Tôi đã có thể sử dụng một phiên bản sửa đổi một chút của mã này từ Thunder. Tôi đã thử nhiều giải pháp đơn giản và đơn giản hơn CSS trên trang này và trên stackoverflow.com/questions/10732690/ và và trên stackoverflow.com/questions/10732690/, nhưng chúng không thể sử dụng được do yêu cầu của tôi. Trang này là một trang Câu hỏi thường gặp với nhiều điểm neo để định vị, cả trên và ngoài trang, do đó có thể có nhiều điểm trống. Tiếp tục trong bình luận tiếp theo ....
Jeffrey Simon

1
Để làm cho nó hoạt động với tôi, đây là những thay đổi nhỏ: (1) thay đổi "<=" trong dòng href.index thành "<" để cho phép điều hướng trên trang; (2) thay đổi "a.navulation" phải là "#faq a" để tôi sử dụng; (3) thay đổi var fromTop = 250 thành một ternary dựa trên window.innerWidth vì sự khác biệt trong thiết bị di động so với máy tính để bàn; (4) thay đổi 400 trong hoạt hình thành 1, vì hoạt ảnh không mong muốn và 0 không hoạt động; (5) thêm if ($ ('my-page-selector'). Độ dài trước cuộc gọi đến offScScrollFromLocation trong chức năng ẩn danh để ngăn các cuộc gọi không cần thiết trên các trang không cần thiết.
Jeffrey Simon

1

Việc triển khai sử dụng :beforerất hiệu quả cho đến khi chúng tôi nhận ra rằng phần tử giả thực sự bao trùm và chặn các sự kiện con trỏ nằm trong khu vực của phần tử giả. Sử dụng một cái gì đó như pointer-events: nonetrên :beforehoặc thậm chí trực tiếp trên neo không có ảnh hưởng.

Điều cuối cùng chúng tôi làm là làm cho vị trí của neo tuyệt đối và sau đó điều chỉnh vị trí của nó thành phần bù / chiều cao của khu vực cố định.

Offset Anchor mà không chặn sự kiện con trỏ

.section-marker {

    position: absolute;
    top: -300px;
}

Giá trị với điều này là chúng tôi không chặn bất kỳ yếu tố nào có thể nằm trong 300px đó. Nhược điểm là việc lấy vị trí của phần tử đó từ Javascript cần phải tính đến phần bù đó để mọi logic phải được điều chỉnh.


1

Đây là cách tôi có được nó để cuối cùng đi đến nơi thích hợp khi bạn nhấp vào điều hướng. Tôi đã thêm một trình xử lý sự kiện cho các nhấp chuột điều hướng. Sau đó, bạn có thể chỉ cần sử dụng "scrollBy" để di chuyển lên phần bù.

var offset = 90;

 $('.navbar li a').click(function(event) {
    event.preventDefault();
    $($(this).attr('href'))[0].scrollIntoView();
    scrollBy(0, -offset);
 });

2
Giải quyết vấn đề, nhưng không phải là phần "không có sự trợ giúp của Javascript" ...
Tomalak

1

Tôi đã tạo một div với một vài ngắt dòng và đưa ra id đó, sau đó tôi đặt mã tôi muốn hiển thị bên dưới. Liên kết sau đó sẽ đưa bạn đến không gian phía trên hình ảnh và tiêu đề sẽ không còn theo cách:

<a href="#image">Image</a>
<div id="image"><br><br></div>
<img src="Image.png">

Tất nhiên, bạn có thể thay đổi số lần ngắt dòng cho phù hợp với nhu cầu của bạn. Điều này làm việc hoàn hảo với tôi, không chắc có vấn đề gì không, tôi vẫn đang học HTML.


Thực dụng, nhưng có một nhược điểm - nó chỉ hoạt động cho tiêu đề đầu tiên trên một trang. Nếu có nhiều tiêu đề hơn, bạn sẽ bắt đầu thấy những khoảng trống lớn trong văn bản vì các <br>thẻ trước mỗi tiêu đề.
Tomalak

1

Đã sử dụng tập lệnh này

$(document).on('click', 'a[href^="#"]', function (event) {
    event.preventDefault();

    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top -140
    }, 1000);
});

Hãy cố gắng giải thích lý do tại sao bạn nghĩ kịch bản này sẽ giải quyết vấn đề
Ali Kanat

1

Tôi nghĩ rằng phương pháp này hữu ích hơn:

<h2 id="bar" title="Bar">Bar</h2>

[id]:target {
    display: block;
    position: relative;
    top: -120px;
    visibility: hidden;
}

[id]:target::before {
    content: attr(title);
    top: 120px;
    position: relative;
    visibility: visible;
}

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.