Header halaman tetap tumpang tindih jangkar dalam halaman


358

Jika saya memiliki tajuk non-gulir di halaman HTML, perbaiki ke atas, dengan ketinggian yang ditentukan:

Apakah ada cara untuk menggunakan jangkar URL ( #fragmentbagian) untuk membuat browser gulir ke titik tertentu di halaman, tetapi tetap menghormati ketinggian elemen tetap tanpa bantuan JavaScript ?

http://foo.com/#bar
SALAH (tetapi perilaku umum): BENAR:
+ --------------------------------- + + -------------- ------------------- +
| BAR ///////////////////// header | | ////////////////////////// header |
+ --------------------------------- + + -------------- ------------------- +
| Ini adalah sisa dari Teks | | BAR |
| ... | | |
| ... | | Ini adalah sisa dari Teks |
| ... | | ... |
+ --------------------------------- + + -------------- ------------------- +



3
@ax YA, itu jawaban terbaik. Juga periksa nicolasgallagher.com/jump-links-and-viewport-positioning/demo di dalamnya. Ini bekerja paling baik untuk saya:.dislocate50px, #bar { padding: 50px 0 0; margin: -50px 0 0; -webkit-background-clip: content-box; background-clip: content-box; }
flen

Saya mencari solusi yang * berfungsi untuk jangkar yang datang dari halaman yang sama atau halaman lain, * dan yang menyesuaikan penekanan tombol halaman-bawah sehingga konten tidak terpotong oleh header, * dan yang memungkinkan footer sib-div untuk gulir ke atas dengan konten-div. Belum menemukan solusi! Tetapi saya harus mengatakan, saya pikir cara yang tepat akan menargetkan seluruh konten div, dan tidak setiap jangkar individu. stackoverflow.com/questions/51070758/…
johny mengapa

@kapak. CSS-tricks.com memiliki artikel baru yang jauh lebih baik tentang di scroll-padding-topsini: css-tricks.com/... Jawaban yang sesuai: stackoverflow.com/a/56467997/247696
Flimm

Jawaban:


167

Saya memiliki masalah yang sama. Saya memecahkannya dengan menambahkan kelas ke elemen jangkar dengan tinggi topbar sebagai nilai padding-top.

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

Dan kemudian css:

.anchor { padding-top: 90px; }

19
@Tomalak Sadarilah bahwa solusi ini membuat tautan di dalam area padding tidak dapat diklik. Untuk memperbaikinya, Anda harus menggunakan indeks-z, dan mengatur nilai tautan lebih tinggi dari jangkar. Ingat Anda topbar harus memiliki nilai indeks-z tertinggi, sehingga konten halaman tidak mengapung di atas topbar saat Anda menggulir.
MutttenXd

Tidak berfungsi di Chrome v28 karena bug posisi tetap WebKit menyebabkan header menghilang. Jawaban ini sangat membantu dalam kasus saya.
Knickedi

2
MuttenXd .. Anda adalah pahlawan saya. Saya mengalami masalah aneh pada tautan yang tidak berfungsi di situs saya (tidak terkait dengan jangkar) membuat saya gila. Komentar Anda yang tidak dapat diklik sangat membantu. Aku berhutang budi padamu!
zipzit

9
Seperti yang disarankan dalam jawaban Roy Shoa, tambahkan margin-top: -90px;untuk mengimbangi celah yang dibuat oleh bantalan.
Skippy le Grand Gourou

37
Saya menggunakan .anchor:target {padding-top: 90px;}sehingga hanya menambahkan padding ketika mereka menggunakan tag anchor. Dengan cara ini tidak selalu ada banyak padding jika halaman memuat di atas. Hanya ketika memuat titik tertentu lebih rendah pada halaman.
jimmyplaysdrums

265

Jika Anda tidak bisa atau tidak ingin mengatur kelas baru, tambahkan ::beforeelemen pseudo- tinggi-tetap ke kelas :targetsemu di CSS:

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

Atau gulir halaman relatif ke :targetdengan jQuery:

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

30
Saya sangat suka solusi Anda. Ini adalah solusi terbersih yang saya temukan.
Itay Grudev

5
Ini adalah solusi yang bekerja sempurna untuk saya tanpa memasukkan apa pun di tata letak halaman saya.
Jamie Carl

2
Solusi CSS memiliki masalah ketika digunakan dengan daftar di WebKit. Lihat: stackoverflow.com/questions/39547773/…
Mert S. Kaplan

14
Ini tidak akan berfungsi jika target memiliki bantalan atas atau perbatasan karena bergantung pada margin-collapse.
krulik

9
:targethanya brilian!
Tak Berujung

125

Saya menggunakan pendekatan ini:

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

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

Itu menambahkan elemen tak terlihat sebelum setiap target. Ini berfungsi IE8 +.

Berikut adalah solusi lainnya: http://nicolasgallagher.com/jump-links-and-viewport-positioning/


lihat tautan yang disediakan Badabam, ada solusi kedua, yang saya gunakan dan yang berfungsi di Chrome dan Firefox
scavenger

Mengujinya pada Firefox terbaru (55.0.3 pada PC) dan berfungsi sekarang. :-)
RachieVee

46

Jawaban Resmi Bootstrap Diadopsi:

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

Kredit

Menggabungkan


1
Terima kasih banyak untuk memasukkan ini, +1 untuk kelengkapannya.
amjoconn

2
Solusi ini memiliki masalah ketika digunakan dengan daftar di WebKit. Lihat: stackoverflow.com/questions/39547773/…
Mert S. Kaplan

Perhatikan bahwa ini tidak akan berfungsi jika elemen target itu sendiri memiliki display: flex;atau padding-top. Jangan gunakan elemen jangkar khusus (seperti <a name="my_link">{leave this empty}</a>) dalam kasus tersebut.
WoodrowShigeru

Ini tidak akan berfungsi jika elemen target adalah <tr>
Ivan Gusev

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

dari: https://css-tricks.com/fixed-headers-on-page-links-and-overlapping-content-oh-my/



Bekerja untukku. Saya menavigasi ke jangkar dari halaman lain. Yang lain tidak bekerja. Terima kasih!
davidloper

1
Ini tidak berfungsi untuk menggulir seluruh halaman di Edge dan Safari ( bugs.webkit.org/show_bug.cgi?id=179379 ).
Juliusz Gonera

1
Penyelamat! Sederhana, langsung. Tidak ada solusi lain yang bekerja untuk saya karena saya menggunakan display: flex. Terima kasih banyak, sangat frustasi mencoba semua solusi.
Priya Payyavula

Ini adalah solusi INDAH, saya menggunakan scroll-behaviour: smooth! Important; juga untuk pergi jangkar, sangat sederhana dalam dua baris kode
yehanny

30

Cara terbaik yang saya temukan untuk menangani masalah ini adalah (ganti 65px dengan tinggi elemen tetap Anda):

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

Jika Anda tidak suka menggunakan pemilih target, Anda juga dapat melakukannya dengan cara ini:

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

Catatan: contoh ini tidak akan berfungsi jika elemen target memiliki warna latar belakang yang berbeda dari orang tuanya. sebagai contoh:

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

dalam hal ini warna hijau elemen target saya akan menimpa elemen merah induknya di 65px. Saya tidak menemukan solusi CSS murni untuk menangani masalah ini tetapi jika Anda tidak memiliki warna latar belakang yang lain, solusi ini adalah yang terbaik.


2
Dari semua jawaban, ini adalah satu-satunya yang berhasil bagi saya!
Javier Arias

18

Sementara beberapa solusi yang diusulkan bekerja untuk tautan fragmen (= tautan hash) di halaman yang sama (seperti tautan menu yang menggulir ke bawah), saya menemukan bahwa tidak ada yang bekerja di Chrome saat ini ketika Anda ingin menggunakan tautan fragmen yang masuk dari yang lain halaman .

Jadi menelepon www.mydomain.com/page.html#foo dari awal TIDAK akan mengimbangi target Anda di Chrome saat ini dengan salah satu dari solusi CSS atau solusi JS yang diberikan.

Ada juga laporan bug jQuery menjelaskan beberapa detail masalah.

LARUTAN

Satu-satunya opsi yang saya temukan sejauh ini yang benar-benar berfungsi di Chrome adalah JavaScript yang tidak dipanggil onDomReady tetapi dengan penundaan.

// 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);
    }
}

RINGKASAN

Tanpa JS penundaan solusi mungkin akan berfungsi di Firefox, IE, Safari, tetapi tidak di Chrome.


3
Saya sampai pada kesimpulan dan solusi yang sama. Sepertinya semua orang lupa tentang tautan eksternal yang menggunakan tagar.
AJJ

Saya punya masalah itu hari ini dan saya sudah menggunakan solusi Anda. Meskipun sepertinya Anda tidak perlu batas waktu. Ini berfungsi sebagai IIFE juga.
kwiat1990

1
@ kwiat1990: Ya, itu dimungkinkan - tetapi hanya jika JS Anda ditempatkan di bagian paling akhir dari kode HTML. Kalau tidak, target gulir Anda mungkin belum berada di DOM. Sebenarnya itulah inti dari menggunakan onDomReady. Jadi saya kira versi batas waktu adalah cara yang stabil untuk pergi.
Jpsy

Jawaban ini adalah satu-satunya yang berfungsi untuk tautan eksternal. Namun itu tidak berfungsi untuk saya ketika tautan dipanggil di halaman yang sama :( Ada ide?
Augusto Samamé Barrientos

@ Agusto apakah Anda menemukan solusi? Saya mengalami masalah yang sama.
Jesse

9

Saat spec CSS Scroll Snap masuk ke dalam game, hal ini mudah dilakukanscroll-margin-top properti . Saat ini berjalan di Chrome dan Opera (April 2019). Safari 11+ juga harus mendukung ini, tetapi saya tidak dapat menjalankannya di Safari 11. Mungkin kita harus menunggu orang untuk memperbaikinya di sana.

Contoh 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
Itu manis sekali. Mari berharap ini bisa diadopsi lebih luas!
Tomalak

Apa perbedaan antara scroll-padding-topdan scroll-margin-top?
Flimm

scroll-margin-topuntuk kasus penggunaan ini sayangnya tidak diterapkan di Safari 11-13: bugs.webkit.org/show_bug.cgi?id=189265
fabb

Di Safari disebut scroll-snap-margin-top: caniuse.com/#search=scroll-margin-top
Mu-Tsun Tsai

@ Mu-TsunTsai Ini sedikit lebih rumit. Ini benar-benar ada di Safari, tetapi tidak bekerja dengan perilaku scroll-to-fragment. Lihat komentar saya di masalah data browser-compat: github.com/mdn/browser-compat-data/issues/…
dakur

8

Untuk Chrome / Safari / Firefox Anda bisa menambahkan display: blockdan menggunakan margin negatif untuk mengkompensasi offset, seperti:

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

Lihat contoh http://codepen.io/swed/pen/RrZBJo


7

Anda dapat melakukan ini dengan jQuery:

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

Bukan ".target", seharusnya ": target"
Mert S. Kaplan

@ MertS.Kaplan ".target" adalah kelas 'target'.
webvitaly

7

Baru saja menemukan solusi CSS murni lain yang berfungsi seperti pesona bagi saya!

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

Ditemukan di situs ini !


2
Beberapa orang lain telah menemukan solusi ini sebelum Anda, lihat jawaban di halaman 1, misalnya stackoverflow.com/a/56467997/18771
Tomalak

Maaf, belum diperhatikan! Terima kasih!
jamawe

Ini tidak berfungsi untuk menggulir seluruh halaman di Edge dan Safari ( bugs.webkit.org/show_bug.cgi?id=179379 ).
Juliusz Gonera

5

Anda bisa mencoba ini:

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

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

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

Setel nilai padding atas ke tinggi aktual header Anda. Ini akan menimbulkan sedikit celah ekstra di bagian atas tajuk Anda, tetapi itu hanya akan terlihat ketika pengguna melompat ke jangkar dan kemudian gulir ke atas. Saya telah membuat solusi untuk situs saya sekarang, tetapi hanya menampilkan bilah tetap kecil di bagian atas halaman, tidak ada yang terlalu tinggi.


Mh Tidak buruk, tetapi masih cukup hack (dan tidak bekerja di IE, sayangnya).
Tomalak

5

Saya sudah membuatnya bekerja dengan mudah dengan CSS dan HTML, menggunakan metode "jangkar: sebelum" yang disebutkan di atas. Saya pikir itu yang terbaik, karena tidak membuat bantalan besar antara divs Anda.

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

Tampaknya tidak berfungsi untuk div pertama di halaman, tetapi Anda bisa mengatasinya dengan menambahkan padding ke div pertama.

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

Ini biola yang berfungsi: http://jsfiddle.net/FRpHE/24/


5

Ini bekerja untuk saya:

LINK HTML ke Anchor:

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

Anchor HTML:

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

CSS:

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

4

Saya menggunakan jawaban Jpsy, tetapi untuk alasan kinerja saya hanya mengatur timer jika hash ada di 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 diminta untuk tidak menggunakan javascript.
Giulio Caccin

Bekerja dengan tautan eksternal tetapi tidak dengan tautan dalam halaman.
jepret

4

Saya punya banyak masalah dengan banyak jawaban di sini dan di tempat lain karena jangkar saya yang dibookmark adalah header bagian di halaman FAQ, jadi mengimbangi header tidak membantu karena konten lainnya hanya akan tetap berada di tempatnya. Jadi saya pikir saya akan memposting.

Apa yang akhirnya saya lakukan adalah gabungan dari beberapa solusi:

  1. CSS:

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

Di mana "120px" adalah tinggi header tetap Anda (mungkin ditambah margin).

  1. HTML tautan bookmark:

    <a href="#01">What is your FAQ question again?</a>
  2. HTML konten yang di-bookmark:

    <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>

Hal yang baik tentang solusi ini adalah bahwa span elemen tersebut tidak hanya disembunyikan, pada dasarnya runtuh dan tidak konten Anda.

Saya tidak dapat mengambil banyak pujian untuk solusi ini karena berasal dari berbagai sumber daya yang berbeda, tetapi ini bekerja paling baik untuk saya dalam situasi saya.

Anda dapat melihat hasil aktual di sini .


1
Terima kasih banyak sudah berbagi! Tua seperti utasnya, sepertinya masih ada satu solusi kanonik untuk masalah ini.
Tomalak

1
+ SteveCinq Anda membaca pikiranku - Saya menghadapi masalah yang sama di mana solusi bersama tidak berfungsi seperti yang diperkirakan. Menambahkan <span>dengan jangkar dalam rentang, bersama dengan menambahkan padding dan margin bekerja untuk saya. Terima kasih banyak telah meluangkan waktu untuk mengirimkan jawaban ini terlepas dari usia utasnya!
twknab

4

Saya tidak beruntung dengan jawaban yang tercantum di atas dan akhirnya menggunakan solusi ini yang bekerja dengan sempurna ...

Buat rentang kosong tempat Anda ingin mengatur jangkar.

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

Dan terapkan kelas berikut:

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

Solusi ini akan berfungsi bahkan jika bagian-bagian memiliki latar belakang berwarna yang berbeda! Saya menemukan solusinya di tautan ini.


1
Bukankah itu metode yang persis sama dengan yang ditunjukkan Guillaume Le Mière dan beberapa lainnya di utas ini?
Tomalak

Ini sangat mirip tetapi saya pikir lebih mudah untuk dipahami dan respons yang lebih rinci dengan tautan yang lebih mendalam ke sumber luar.
Matt Underwood

Ini adalah solusi yang sama, tetapi saya dapat memahami dan mengikuti yang ini dengan mudah. Yang lain tidak memberi saya informasi yang cukup.
MacroMan

3

Rasanya agak gila di pikiran saya, tetapi sebagai solusi css saja Anda dapat menambahkan padding ke elemen berlabuh aktif menggunakan :targetpemilih:

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
Itu sama sekali tidak aneh! Solusi yang bagus.
Tomalak

3

Saya menemukan saya harus menggunakan kedua MutttenXd 's dan Badabam ' solusi CSS s bersama-sama, sebagai yang pertama tidak bekerja di Chrome dan yang kedua tidak bekerja di 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

Cara saya menemukan menjadi terbersih adalah yang berikut:

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

2

Pendekatan intrusif minimal menggunakan jQuery:

Tautan:

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

Kandungan:

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

Naskah:

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

Dengan menetapkan kelas tautan-jangkar ke tautan, perilaku tautan lain (seperti akordeon atau kontrol tab) tidak terpengaruh.

Pertanyaannya tidak ingin javascript tetapi pertanyaan lain yang lebih populer ditutup karena yang ini dan saya tidak bisa menjawabnya.


2

Saya membutuhkan sesuatu yang berfungsi untuk tautan masuk, tautan di halaman, DAN yang dapat ditargetkan oleh JS sehingga laman dapat menanggapi perubahan ketinggian header.

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;
}

Itu z-index: -1 memungkinkan link di 'daerah bantalan' di atas sebuah fragmen-target yang masih dapat diklik, seperti berkomentar oleh @MuttenXd pada jawabannya

Saya belum menemukan masalah di IE 11, Edge 15+, Chrome 38+, FF 52+, atau Safari 9.1+


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

Kode ini harus melakukan trik. Tukar 45px untuk ketinggian bilah header Anda.

EDIT: Jika menggunakan jQuery adalah sebuah opsi, saya juga telah berhasil menggunakan jQuery.localScroll dengan set nilai offset. Opsi offset adalah bagian dari jQuery.scrollTo, yang menjadi dasar jQuery.localScroll. Demo tersedia di sini: http://demos.flesler.com/jquery/scrollTo/ (jendela kedua, di bawah 'offset')


solusi ini memang bekerja, tetapi tidak anti peluru dan membutuhkan banyak finetuning untuk browser yang berbeda :( coba baik-baik saja. Saya sedang mencari solusi tanpa markup tambahan.
vlad saling

Malu ini sangat berantakan, berarti Anda tidak bisa hanya menggunakan ID. Senang mencari solusi, saya sudah mencoba segala macam hal.
berteori

1

Berikut ini adalah solusi jquery lengkap yang akan bekerja di IE:

Misalkan elemen bilah navigasi adalah seperti ini:

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

Anda dapat menggunakan cuplikan jquery berikut untuk mengimbangi gulir:

$(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) {

    });
}

Saya dapat menggunakan versi kode ini yang sedikit dimodifikasi dari Thunder. Saya mencoba banyak solusi CSS saja dan lebih sederhana di halaman ini dan di stackoverflow.com/questions/10732690/… dan di stackoverflow.com/questions/10732690/… tapi itu tidak dapat digunakan karena persyaratan saya. Halaman ini adalah halaman FAQ dengan banyak jangkar untuk diposisikan, baik dari dalam dan luar halaman, sehingga bisa memiliki banyak tempat kosong. Melanjutkan komentar berikutnya ....
Jeffrey Simon

1
Untuk membuatnya berfungsi untuk saya, berikut adalah perubahan kecil: (1) ubah "<=" pada baris href.index ke "<" untuk memungkinkan navigasi di halaman; (2) ubah "navigasi web" yang harus menjadi "#faq a" untuk penggunaan saya; (3) ubah var dariTop = 250 ke ternary berdasarkan window.innerWidth untuk perbedaan dalam mobile vs desktop; (4) ubah 400 di animate ke 1, karena animasi tidak diinginkan dan 0 tidak berfungsi; (5) tambahkan if ($ ('my-page-selector'). Panjang sebelum panggilan untuk offSetScrollFromLocation dalam fungsi anonim untuk mencegah panggilan yang tidak perlu pada halaman di mana tidak diperlukan.
Jeffrey Simon

1

Diimplementasikan menggunakan :beforeberfungsi dengan baik sampai kami menyadari bahwa elemen pseudo sebenarnya menutupi dan memblokir peristiwa pointer yang berada di dalam area elemen pseudo. Menggunakan sesuatu seperti pointer-events: nonepada :beforeatau bahkan langsung pada jangkar tidak berpengaruh.

Apa yang akhirnya kami lakukan adalah membuat posisi jangkar menjadi absolut dan kemudian menyesuaikan posisinya menjadi offset / ketinggian area tetap.

Jangkar Offset tanpa Peristiwa Blocker Pointer

.section-marker {

    position: absolute;
    top: -300px;
}

Nilai dengan ini adalah bahwa kami tidak memblokir elemen apa pun yang mungkin termasuk dalam 300px tersebut. The downside adalah bahwa mengambil posisi elemen itu dari Javascript perlu memperhitungkan yang mengimbangi sehingga setiap logika harus disesuaikan.


1

Ini adalah bagaimana saya mendapatkannya untuk akhirnya pergi ke tempat yang tepat ketika Anda mengklik navigasi. Saya menambahkan pengendali acara untuk klik navigasi. Kemudian Anda bisa menggunakan "scrollBy" untuk naik pada offset.

var offset = 90;

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

2
Memecahkan masalah, tetapi bukan bagian "tanpa bantuan Javascript" ...
Tomalak

1

Saya membuat div dengan beberapa jeda baris dan memberikan id itu, saya kemudian meletakkan kode yang ingin saya perlihatkan di bawahnya. Tautan kemudian akan membawa Anda ke ruang di atas gambar dan tajuk tidak akan lagi menghalangi:

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

Tentu saja, Anda dapat mengubah jumlah jeda baris sesuai dengan kebutuhan Anda. Ini berfungsi dengan baik untuk saya, tidak yakin apakah ada masalah, saya masih belajar HTML.


Pragmatis, tetapi ada sisi buruknya - ini hanya berfungsi untuk judul pertama pada halaman. Jika ada lebih banyak judul, Anda akan mulai melihat celah besar di teks karena <br>tag sebelum setiap pos.
Tomalak

1

Gunakan skrip ini

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

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

Coba jelaskan mengapa menurut Anda skrip ini akan menyelesaikan masalah
Ali Kanat

1

Saya pikir pendekatan ini lebih bermanfaat:

<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;
}

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.