ส่วนหัวของหน้าคงทับซ้อนกับจุดยึดในหน้า


358

หากฉันมีส่วนหัวที่ไม่เลื่อนในหน้า HTML จับจ้องไปที่ด้านบนมีความสูงที่กำหนด:

มีวิธีใช้ตัวยึด URL ( #fragmentส่วน) เพื่อให้เบราว์เซอร์เลื่อนไปยังจุดที่แน่นอนในหน้า แต่ยังคงเคารพความสูงขององค์ประกอบคงที่โดยความช่วยเหลือของ JavaScriptหรือไม่

http://foo.com/#bar
ผิด (แต่เป็นพฤติกรรมปกติ): ถูกต้อง:
+ --------------------------------- + + -------------- ------------------- +
| BAR /////////////////////// ส่วนหัว | | //////////////////////// // ส่วนหัว |
+ --------------------------------- + + -------------- ------------------- +
| นี่คือส่วนที่เหลือของข้อความ | | บาร์ |
| ... | | |
| ... | | นี่คือส่วนที่เหลือของข้อความ |
| ... | | ... |
+ --------------------------------- + + -------------- ------------------- +

3
ที่เกี่ยวข้อง: stackoverflow.com/questions/10732690/…
0fnt


3
@ax YES นั่นเป็นคำตอบที่ดีที่สุด ตรวจสอบnicolasgallagher.com/jump-links-and-viewport-positioning/demoภายในด้วย สิ่งนี้ทำงานได้ดีที่สุดสำหรับฉัน:.dislocate50px, #bar { padding: 50px 0 0; margin: -50px 0 0; -webkit-background-clip: content-box; background-clip: content-box; }
flen

ฉันกำลังค้นหาโซลูชันที่ * ใช้ได้กับแองเคอร์ที่มาจากหน้าเดียวกันหรือหน้าอื่น ๆ * และปรับการกดปุ่มหน้าลงเพื่อให้เนื้อหาไม่ถูกตัดโดยส่วนหัว * และช่วยให้ส่วนท้ายของ Sib-div เลื่อนขึ้นด้วย div เนื้อหา ยังไม่พบวิธีแก้ปัญหา! แต่ฉันต้องบอกว่าฉันคิดว่าวิธีที่ถูกต้องจะกำหนดเป้าหมายเนื้อหาทั้งหมด div ไม่ใช่แต่ละสมอ stackoverflow.com/questions/51070758/…
johny ทำไม

@ขวาน. CSS-tricks.com มีบทความใหม่ที่ดีกว่าเกี่ยวกับscroll-padding-topที่นี่: css-tricks.com/…คำตอบที่สอดคล้องกัน: stackoverflow.com/a/56467997/247696
Flimm

คำตอบ:


167

ผมมีปัญหาเดียวกัน. ฉันแก้ไขมันโดยการเพิ่มคลาสให้กับองค์ประกอบสมอด้วยความสูงของแถบด้านบนเป็นค่าเสริมด้านบน

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

แล้วเพียงแค่ CSS:

.anchor { padding-top: 90px; }

19
@Tomalak โปรดระวังว่าโซลูชันนี้สร้างลิงก์ภายในพื้นที่การแพ็ดที่ไม่สามารถคลิกได้ ในการแก้ไขปัญหานี้คุณต้องใช้ดัชนี z และตั้งค่าลิงค์ให้สูงกว่าจุดยึด โปรดจำไว้ว่าแถบด้านบนของคุณควรมีค่าดัชนีสูงสุดดังนั้นเนื้อหาของหน้าเว็บจึงไม่ลอยไปด้านบนของแถบด้านบนเมื่อคุณเลื่อน
MutttenXd

ไม่ทำงานใน Chrome v28 เนื่องจากข้อผิดพลาดตำแหน่งคงที่ของ WebKit ทำให้ส่วนหัวหายไป คำตอบนี้ได้หลอกลวงฉันกรณีของ
Knickedi

2
MuttenXd .. คุณคือฮีโร่ของฉัน ฉันมีปัญหาการเชื่อมโยงที่ไม่ใช่ฟังก์ชั่นแปลก ๆ บนเว็บไซต์ของฉัน (ไม่เกี่ยวข้องกับแองเคอร์) ทำให้ฉันบ้า ความคิดเห็นที่ไม่สามารถคลิกได้ของคุณช่วยได้จริงๆ ฉันเป็นหนี้ยาตัวใหญ่!
zipzit

9
ตามที่แนะนำไว้ในคำตอบของ Roy Shoa ให้เพิ่มmargin-top: -90px;การตอบโต้ช่องว่างที่เกิดจากการเติมเต็ม
Skippy le Grand Gourou

37
ฉันใช้.anchor:target {padding-top: 90px;}เพื่อที่จะเพิ่มการขยายเมื่อพวกเขาใช้แท็กจุดยึดเท่านั้น วิธีนี้จะมีช่องว่างภายในไม่มากนักหากหน้าเว็บโหลดที่ด้านบนสุด เฉพาะเมื่อมันโหลดจุดเฉพาะที่ต่ำกว่าบนหน้า
jimmyplaysdrums

265

หากคุณไม่สามารถหรือไม่ต้องการตั้งคลาสใหม่ให้เพิ่ม::beforeองค์ประกอบ:targetหลอกระดับความสูงคงที่ให้กับคลาสหลอกใน CSS:

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

หรือเลื่อนหน้าเทียบ:targetกับ jQuery:

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

30
ฉันชอบทางออกของคุณจริงๆ มันเป็นทางออกที่สะอาดที่สุดที่ฉันพบ
Itay Grudev

5
นี่เป็นวิธีการแก้ปัญหาที่ทำงานได้อย่างสมบูรณ์แบบสำหรับฉันโดยไม่ต้องบรรจุอะไรในเค้าโครงหน้าของฉัน
Jamie Carl

2
วิธีแก้ปัญหา CSS มีปัญหาเมื่อใช้กับรายการใน WebKit ดู: stackoverflow.com/questions/39547773/…
Mert S. Kaplan

14
มันจะไม่ทำงานถ้าเป้าหมายมีช่องว่างภายในหรือขอบด้านบนเนื่องจากอาศัยการลดลงของอัตรากำไรขั้นต้น
krulik

9
:targetมันยอดเยี่ยมมาก!
ไม่มีที่สิ้นสุด

125

ฉันใช้วิธีนี้:

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

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

มันเพิ่มองค์ประกอบที่มองไม่เห็นก่อนเป้าหมาย มันใช้งานได้กับ IE8 +

นี่คือโซลูชันเพิ่มเติม: http://nicolasgallagher.com/jump-links-and-viewport-positioning/


ดูลิงค์ Badabam ที่ให้ไว้มีทางออกที่สองซึ่งฉันใช้และใช้งานได้ใน Chrome และ Firefox
กินของเน่า

ทดสอบสิ่งนี้กับ Firefox ล่าสุด (55.0.3 บนพีซี) และใช้งานได้ทันที :-)
RachieVee

46

Bootstrap อย่างเป็นทางการยอมรับคำตอบ:

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

เครดิต

ผสาน


1
ขอบคุณมากสำหรับการรวมสิ่งนี้ +1 เพื่อความสมบูรณ์
amjoconn

2
วิธีนี้มีปัญหาเมื่อใช้กับรายการใน WebKit ดู: stackoverflow.com/questions/39547773/…
Mert S. Kaplan

หมายเหตุที่ว่านี้จะไม่ทำงานหากองค์ประกอบเป้าหมายที่ตัวเองเกิดขึ้นจะมีหรือdisplay: flex; padding-topใช้องค์ประกอบจุดยึดเฉพาะ (เช่น<a name="my_link">{leave this empty}</a>) ในกรณีเหล่านั้น
WoodrowShigeru

สิ่งนี้จะไม่ทำงานหากองค์ประกอบเป้าหมายคือ <tr>
Ivan Gusev

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

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


การสนับสนุนเบราว์เซอร์: caniuse.com/#feat=mdn-css_properties_scroll-padding-top
Flimm

ได้ผลสำหรับฉัน ฉันไปที่จุดยึดจากหน้าอื่น คนอื่นไม่ทำงาน ขอบคุณ!
davidloper

1
สิ่งนี้ใช้ไม่ได้กับการเลื่อนทั้งหน้าใน Edge และ Safari ( bugs.webkit.org/show_bug.cgi?id=179379 )
Juliusz Gonera

1
ผู้ช่วยให้รอด! ง่ายตรงประเด็น ไม่มีวิธีแก้ปัญหาอื่นที่ใช้ได้ผลสำหรับฉันเพราะฉันใช้จอแสดงผล: เฟล็กซ์ ขอบคุณตันมันน่าผิดหวังมากที่พยายามแก้ปัญหาทั้งหมด
Priya Payyavula

นี่เป็นทางออกที่สวยงามฉันใช้ scroll-behavior: ราบรื่น! สำคัญ ง่ายมากในการเขียนโค้ดสองบรรทัด
Yehanny

30

วิธีที่ดีที่สุดที่ฉันพบเพื่อจัดการปัญหานี้คือ (แทนที่ 65px ด้วยความสูงองค์ประกอบคงที่ของคุณ):

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

หากคุณไม่ต้องการใช้ตัวเลือกเป้าหมายคุณสามารถทำได้ด้วยวิธีนี้:

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

หมายเหตุ: ตัวอย่างนี้จะไม่ทำงานหากองค์ประกอบเป้าหมายมีสีพื้นหลังที่แตกต่างจากแม่ของเขา ตัวอย่างเช่น:

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

ในกรณีนี้สีเขียวขององค์ประกอบเป้าหมายของฉันจะเขียนทับองค์ประกอบสีแดงหลักของเขาใน 65px ฉันไม่พบโซลูชัน CSS บริสุทธิ์ใด ๆ ที่จะจัดการกับปัญหานี้ แต่ถ้าคุณไม่มีสีพื้นหลังอื่นโซลูชันนี้ดีที่สุด


2
จากคำตอบทั้งหมดนี่เป็นคำตอบเดียวที่ได้ผลสำหรับฉัน!
Javier Arias

18

แม้ว่าโซลูชันที่เสนอบางข้อสามารถใช้งานได้กับลิงก์แฟรกเมนต์ (= ลิงก์แฮช) ในหน้าเดียวกัน (เช่นลิงก์เมนูที่เลื่อนลง) ฉันพบว่าไม่มีการทำงานใด ๆ ใน Chrome ปัจจุบันเมื่อคุณต้องการใช้ลิงก์แฟรกเมนต์ที่มาจากที่อื่น หน้า

ดังนั้นการโทร www.mydomain.com/page.html#foo ตั้งแต่เริ่มต้นจะไม่ชดเชยเป้าหมายของคุณใน Chrome ปัจจุบันด้วยโซลูชัน CSS หรือโซลูชัน JS ที่กำหนด

นอกจากนี้ยังมีรายงานข้อผิดพลาด jQuery ที่อธิบายรายละเอียดของปัญหา

สารละลาย

ตัวเลือกเดียวที่ฉันพบจนถึงขณะนี้ที่ใช้งานได้จริงใน Chrome คือ JavaScript ที่ไม่ได้เรียกว่า onDomReady แต่มีความล่าช้า

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

สรุป

หากไม่มีวิธีแก้ปัญหาความล่าช้าของ JS อาจทำงานได้ใน Firefox, IE, Safari แต่ไม่ใช่ใน Chrome


3
ฉันได้ข้อสรุปและวิธีแก้ปัญหาเดียวกันมาแล้ว ดูเหมือนว่าทุกหน่วยงานจะลืมเกี่ยวกับลิงก์ภายนอกที่ใช้แฮชแท็ก
AJJ

ฉันมีปัญหานั้นวันนี้และฉันใช้วิธีแก้ปัญหาของคุณ แม้ว่าดูเหมือนว่าคุณไม่ต้องการหมดเวลา ใช้งานได้เหมือน IIFE เช่นกัน
kwiat1990

1
@ kwiat1990: ใช่มันอาจเป็นไปได้ - แต่ถ้าวาง JS ไว้ที่ส่วนท้ายสุดของโค้ด HTML มิฉะนั้นเป้าหมายการเลื่อนของคุณอาจยังไม่ได้อยู่ใน DOM จริง ๆ แล้วนั่นคือจุดรวมของการใช้บน DomReady ดังนั้นฉันเดารุ่นหมดเวลาเป็นวิธีที่มั่นคงที่จะไป
Jpsy

คำตอบนี้เป็นคำตอบเดียวที่ใช้ได้กับลิงก์ภายนอก อย่างไรก็ตามมันไม่ได้ผลสำหรับฉันเมื่อมีการเรียกลิงก์ในหน้าเดียวกัน :( มีความคิดเห็นอะไรบ้าง?
Augusto Samamé Barrientos

@Augusto คุณหาทางออกหรือไม่? ฉันมีปัญหาเดียวกัน
เจสซี

9

เมื่อCSS Scroll Snap สเป็คเข้ามาในเกมจึงเป็นไปได้อย่างง่ายดายด้วยscroll-margin-topคุณสมบัติ ปัจจุบันทำงานบน Chrome และ Opera (เมษายน 2019) Safari 11+ ก็ควรสนับสนุนสิ่งนี้เช่นกัน แต่ฉันไม่สามารถเรียกใช้บน Safari 11 ได้เราอาจต้องรอให้คนอื่นแก้ไขมันให้ได้

ตัวอย่าง 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
นั่นหวานมาก หวังว่ามันจะได้รับการยอมรับอย่างกว้างขวางมากขึ้น!
Tomalak

ความแตกต่างระหว่างscroll-padding-topและscroll-margin-topคืออะไร?
Flimm

scroll-margin-topสำหรับกรณีการใช้งานนี้น่าเสียดายที่ไม่มีการใช้งานใน Safari 11-13: bugs.webkit.org/show_bug.cgi?id=189265
fabb

ใน Safari เรียกว่าscroll-snap-margin-top: caniuse.com/#search=scroll-margin-top
Mu-Tsun Tsai

@ Mu-TsunTsai มันซับซ้อนกว่าเล็กน้อย สิ่งนี้มีอยู่จริงบน Safari แต่มันไม่สามารถทำงานได้กับพฤติกรรมการเลื่อนเพื่อส่วน ดูความคิดเห็นของฉันในปัญหาเบราว์เซอร์ที่เข้ากันได้กับข้อมูล: github.com/mdn/browser-compat-data/issues/ …
dakur

8

สำหรับ Chrome / Safari / Firefox คุณสามารถเพิ่มdisplay: blockและใช้มาร์จิ้นติดลบเพื่อชดเชยออฟเซตเช่น:

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

ดูตัวอย่างhttp://codepen.io/swed/pen/RrZBJo


7

คุณสามารถทำได้ด้วย jQuery:

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

ไม่ใช่ ".target" ควรเป็น ": target"
Mert S. Kaplan

@ MertS.Kaplan ".target" เป็น 'เป้าหมาย' ของคลาส
webvitaly

7

เพิ่งค้นพบวิธีแก้ปัญหา CSS บริสุทธิ์อื่นที่ใช้งานได้ดีสำหรับฉัน!

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

พบในเว็บไซต์นี้ !


2
มีอีกไม่กี่คนที่ค้นพบวิธีแก้ไขปัญหานี้ก่อนที่คุณจะเห็นคำตอบในหน้า 1 เช่นstackoverflow.com/a/56467997/18771
Tomalak

ขออภัยไม่ได้สังเกต! ขอบคุณ!
jamawe

สิ่งนี้ใช้ไม่ได้กับการเลื่อนทั้งหน้าใน Edge และ Safari ( bugs.webkit.org/show_bug.cgi?id=179379 )
Juliusz Gonera

5

คุณสามารถลองสิ่งนี้:

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

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

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

ตั้งค่าการเติมด้านบนเป็นความสูงจริงของส่วนหัวของคุณ วิธีนี้จะแนะนำช่องว่างพิเศษเล็กน้อยที่ด้านบนของส่วนหัวของคุณ แต่จะปรากฏเฉพาะเมื่อผู้ใช้ข้ามไปที่จุดยึดแล้วเลื่อนขึ้น ฉันได้สร้างโซลูชันสำหรับเว็บไซต์ของฉันในตอนนี้ แต่มันแสดงแถบคงที่เล็ก ๆ ที่ด้านบนของหน้าเท่านั้นไม่มีอะไรสูงเกินไป


Mh ไม่เลว แต่ยังค่อนข้างแฮ็ค (และไม่ทำงานใน IE เศร้า)
Tomalak

5

ฉันทำให้มันทำงานได้อย่างง่ายดายกับ CSS และ HTML โดยใช้วิธี "anchor: before" ที่กล่าวถึงข้างต้น ฉันคิดว่ามันใช้งานได้ดีที่สุดเพราะมันไม่ได้สร้างช่องว่างขนาดใหญ่ระหว่าง div ของคุณ

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

ดูเหมือนจะใช้งานไม่ได้สำหรับ div แรกบนหน้าเว็บ แต่คุณสามารถตอบโต้ด้วยการเพิ่ม padding ไปที่ div แรก

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

นี่คือซอที่ใช้งานได้: http://jsfiddle.net/FRpHE/24/


5

มันเหมาะกับฉัน:

ลิงค์ HTML ไปที่ Anchor:

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

HTML Anchor:

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

CSS:

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

4

ฉันใช้คำตอบ @ Jpsy แต่ด้วยเหตุผลด้านประสิทธิภาพฉันตั้งค่าตัวจับเวลาเฉพาะเมื่อแฮชมีอยู่ใน 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 ขอให้ไม่ใช้จาวาสคริปต์
Giulio Caccin

ใช้ได้กับลิงค์ภายนอก แต่ไม่สามารถใช้กับลิงค์ในหน้าได้
snap

4

ฉันมีปัญหากับคำตอบมากมายที่นี่และที่อื่น ๆ เนื่องจากจุดยึดที่คั่นหน้าของฉันเป็นส่วนหัวในหน้าคำถามที่พบบ่อยดังนั้นการชดเชยส่วนหัวไม่ได้ช่วยเพราะเนื้อหาที่เหลือจะอยู่ที่เดิม ดังนั้นฉันคิดว่าฉันโพสต์

สิ่งที่ฉันทำคือการรวมกันของการแก้ปัญหาบาง

  1. CSS:

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

โดยที่ "120px" คือความสูงส่วนหัวคงที่ของคุณ (อาจเพิ่มระยะขอบบางส่วน)

  1. ลิงก์บุ๊กมาร์ก HTML:

    <a href="#01">What is your FAQ question again?</a>
  2. 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>

สิ่งที่ดีเกี่ยวกับการแก้ปัญหานี้คือspanองค์ประกอบไม่เพียง แต่ซ่อนอยู่ แต่มันก็ยุบตัวลงและไม่ได้ทำลายเนื้อหาของคุณ

ฉันไม่สามารถได้รับเครดิตจำนวนมากสำหรับโซลูชันนี้เนื่องจากมาจากทรัพยากรที่แตกต่างกันมากมาย แต่มันทำงานได้ดีที่สุดสำหรับฉันในสถานการณ์ของฉัน

ท่านสามารถเข้าดูผลที่เกิดขึ้นจริงที่นี่


1
ขอบคุณมากสำหรับการแบ่งปัน! เก่าเท่าที่มีเธรดดูเหมือนว่าจะยังไม่มีวิธีแก้ปัญหาแบบบัญญัติสำหรับปัญหานี้
Tomalak

1
+ SteveCinq คุณอ่านใจของฉัน - ฉันกำลังเผชิญปัญหาเดียวกันกับที่โซลูชันที่ใช้ร่วมกันไม่ทำงานตามที่คาดการณ์ไว้ เพิ่มใน<span>กับสมอในช่วงพร้อมกับเพิ่มใน padding และระยะขอบทำงานสำหรับฉัน ขอบคุณมากที่สละเวลาในการส่งคำตอบนี้แม้อายุของเธรด!
twknab

4

ฉันไม่มีโชคกับคำตอบข้างต้นและลงเอยด้วยการใช้โซลูชันนี้ซึ่งทำงานได้อย่างสมบูรณ์แบบ ...

สร้างช่วงว่างเปล่าที่คุณต้องการตั้งค่าจุดยึดของคุณ

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

และใช้คลาสต่อไปนี้:

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

วิธีการแก้ปัญหานี้จะทำงานแม้ว่าส่วนที่มีพื้นหลังสีแตกต่างกัน! ฉันพบวิธีแก้ปัญหาที่ลิงก์นี้


1
นั่นไม่ใช่วิธีเดียวกันกับที่Guillaume Le Mièreและคนอื่น ๆ ได้แสดงไว้ในกระทู้นี้หรือไม่?
Tomalak

มันคล้ายกันมาก แต่ฉันคิดว่ามันง่ายกว่าที่จะเข้าใจและตอบสนองโดยละเอียดยิ่งขึ้นด้วยลิงก์เชิงลึกยิ่งขึ้นไปยังแหล่งข้อมูลภายนอก
Matt Underwood

มันเป็นทางออกเดียวกัน แต่ฉันสามารถเข้าใจและติดตามได้อย่างง่ายดาย คนอื่นไม่ให้ข้อมูลฉันเพียงพอ
MacroMan

3

มันค่อนข้างแฮ็คในใจคนเจ้าระเบียบของฉัน แต่ในฐานะที่เป็น css-only คุณสามารถเพิ่มช่องว่างภายในองค์ประกอบที่ยึดไว้โดยใช้:targetตัวเลือก:

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
นั่นไม่ใช่แฮ็คเลย! ทางออกที่ดี
Tomalak

3

ฉันพบว่าฉันต้องใช้ทั้ง CSSของMutttenXdและBadabamร่วมกันเนื่องจากวิธีแรกไม่ได้ทำงานใน Chrome และตัวที่สองไม่ทำงานใน 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

วิธีที่ฉันพบว่าสะอาดที่สุดคือวิธีต่อไปนี้:

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

2

วิธีการล่วงล้ำน้อยที่สุดโดยใช้ jQuery:

Link:

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

เนื้อหา:

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

สคริปต์:

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

โดยการกำหนดคลาส anchor-link ให้กับลิงก์พฤติกรรมของลิงก์อื่น ๆ (เช่นการควบคุมหีบเพลงหรือแท็บ) จะไม่ได้รับผลกระทบ

คำถามไม่ต้องการจาวาสคริปต์ แต่คำถามยอดนิยมอื่น ๆถูกปิดเนื่องจากคำถามนี้และฉันไม่สามารถตอบได้


2

ฉันต้องการบางสิ่งที่ใช้ได้กับลิงก์ขาเข้าลิงก์ในหน้าและที่สามารถกำหนดเป้าหมายโดย JS เพื่อให้หน้าสามารถตอบสนองต่อการเปลี่ยนแปลงความสูงของส่วนหัว

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

z-index: -1ช่วยให้การเชื่อมโยงใน 'พื้นที่ padding' เหนือส่วนเป้าหมายยังคงสามารถคลิกได้ตามที่แสดงความเห็นโดย @MuttenXd ในคำตอบของเขา

ฉันยังไม่พบปัญหาใน IE 11, Edge 15+, Chrome 38+, FF 52+ หรือ Safari 9.1+


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

รหัสนี้ควรทำเคล็ดลับ สลับ 45px สำหรับความสูงของแถบส่วนหัวของคุณ

แก้ไข: หากใช้ jQuery เป็นตัวเลือกฉันก็ประสบความสำเร็จในการใช้ jQuery.localScroll ด้วยชุดค่าออฟเซ็ต ตัวเลือกออฟเซ็ตเป็นส่วนหนึ่งของ jQuery.scrollTo ซึ่ง jQuery.localScroll ถูกสร้างขึ้น มีตัวอย่างให้ดูที่นี่: http://demos.flesler.com/jquery/scrollTo/ (หน้าต่างที่สองภายใต้ 'offset')


วิธีนี้ใช้งานได้จริง แต่ไม่กันกระสุนและต้องใช้ finetuning สำหรับเบราว์เซอร์ที่แตกต่างกัน :( ลองดีเจ้าฉันกำลังค้นหาวิธีการแก้ปัญหาโดยไม่ต้องมาร์กอัปเพิ่มเติม
vlad saling

ความอัปยศนี่มันยุ่งมากหมายความว่าคุณไม่สามารถใช้ ID ได้ ชอบที่จะหาทางออกฉันได้ลองทุกสิ่ง
ทฤษฎี

1

นี่คือ jquery solution ที่สมบูรณ์ที่จะทำงานใน IE:

สมมติว่าองค์ประกอบแถบนำทางมีลักษณะดังนี้:

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

คุณสามารถใช้ตัวอย่าง jquery ต่อไปนี้เพื่อชดเชยการเลื่อน:

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

    });
}

ฉันสามารถใช้รหัสนี้ที่ดัดแปลงเล็กน้อยจาก Thunder ฉันลองใช้ CSS-only และ simple solution บนหน้านี้และในstackoverflow.com/questions/10732690/…และบนstackoverflow.com/questions/10732690/แต่พวกเขาไม่สามารถใช้งานได้เนื่องจากความต้องการของฉัน หน้านี้เป็นหน้าคำถามที่พบบ่อยซึ่งมีจุดยึดมากมายที่จะวางตำแหน่งทั้งจากเปิดและปิดหน้าดังนั้นอาจมีจุดว่างจำนวนมาก อย่างต่อเนื่องในความคิดเห็นต่อไป ....
เจฟฟรีย์ไซมอน

1
เพื่อให้มันใช้งานได้สำหรับฉันนี่คือการเปลี่ยนแปลงเล็กน้อย: (1) เปลี่ยน "<=" ในบรรทัด href.index เป็น "<" เพื่ออนุญาตการนำทางในหน้า; (2) เปลี่ยน "a.navigation" ที่ต้องเป็น "#faq a" สำหรับการใช้งานของฉัน (3) เปลี่ยน var fromTop = 250 เป็นไตรภาคตาม window.innerWidth สำหรับความแตกต่างในมือถือและเดสก์ท็อป (4) เปลี่ยน 400 ในภาพเคลื่อนไหวเป็น 1 เนื่องจากไม่ต้องการภาพเคลื่อนไหวและ 0 ไม่ทำงาน (5) เพิ่มถ้า ($ ('my-page-selector'). ความยาวก่อนการเรียกไปยัง offSetScrollFromLocation ในฟังก์ชั่นที่ไม่ระบุชื่อเพื่อป้องกันการโทรที่ไม่จำเป็นบนหน้าเว็บที่ไม่จำเป็น
Jeffrey Simon

1

การใช้งานนั้นใช้:beforeงานได้ดีจนกระทั่งเราตระหนักว่าองค์ประกอบปลอมนั้นถูกปกปิดและปิดกั้นเหตุการณ์ของตัวชี้ที่อยู่ภายในพื้นที่ขององค์ประกอบหลอก การใช้บางอย่างเช่นpointer-events: noneบน:beforeหรือแม้กระทั่งบนสมอโดยตรงจะไม่มีผลกระทบใด ๆ

สิ่งที่เราทำลงไปคือการทำให้ตำแหน่งของสมอเรือสมบูรณ์และจากนั้นปรับตำแหน่งให้เป็นออฟเซ็ต / ความสูงของพื้นที่คงที่

Offset Anchor โดยไม่ปิดกั้นกิจกรรมของตัวชี้

.section-marker {

    position: absolute;
    top: -300px;
}

คุณค่าของสิ่งนี้คือเราไม่ได้ปิดกั้นองค์ประกอบใด ๆ ที่อาจตกอยู่ภายใน 300px เหล่านั้น ข้อเสียคือการคว้าตำแหน่งขององค์ประกอบนั้นจาก Javascript ต้องคำนึงถึงว่าออฟเซ็ตจึงต้องปรับตรรกะใด ๆ


1

นี่คือวิธีที่ฉันได้รับไปในที่สุดไปยังสถานที่ที่เหมาะสมเมื่อคุณคลิกที่การนำทาง ฉันเพิ่มตัวจัดการเหตุการณ์สำหรับการนำทางการนำทาง จากนั้นคุณสามารถใช้ "scrollBy" เพื่อเลื่อนขึ้นบนออฟเซ็ต

var offset = 90;

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

2
แก้ปัญหา แต่ไม่ใช่ส่วนที่ "ไม่ได้ใช้ Javascript" ...
Tomalak

1

ฉันสร้าง div ที่มีการขึ้นบรรทัดใหม่ไม่กี่ครั้งและให้รหัสนั้นฉันใส่รหัสที่ฉันต้องการแสดงภายใต้ ลิงก์จะนำคุณไปยังพื้นที่ด้านบนของภาพและส่วนหัวจะไม่ขวางหน้า:

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

แน่นอนคุณสามารถเปลี่ยนจำนวนการขึ้นบรรทัดใหม่เพื่อให้เหมาะกับความต้องการของคุณ สิ่งนี้ทำงานได้อย่างสมบูรณ์แบบสำหรับฉันไม่แน่ใจว่ามีปัญหาใด ๆ หรือไม่ฉันยังคงเรียนรู้ HTML อยู่


ในทางปฏิบัติ แต่มีข้อเสีย - ใช้ได้เฉพาะกับหัวข้อแรกบนหน้าเว็บ หากมีส่วนหัวเพิ่มเติมคุณจะเริ่มเห็นช่องว่างขนาดใหญ่ในข้อความเนื่องจาก<br>แท็กก่อนแต่ละส่วนหัว
Tomalak

1

ใช้สคริปต์นี้

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

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

โปรดอธิบายเหตุผลที่คุณคิดว่าสคริปต์นี้จะช่วยแก้ปัญหาได้
Ali Kanat

1

ฉันคิดว่าวิธีนี้มีประโยชน์มากกว่า:

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

1

ตอนนี้คุณสามารถใช้เลื่อนขอบด้านบนซึ่งเป็นที่รักการยอมรับอย่างกว้างขวาง

เพียงเพิ่ม CSS ต่อไปนี้ในองค์ประกอบที่คุณต้องการเลื่อนไปที่:

.element {
  scroll-margin-top: 2em;
}

scroll-margin-topได้รับการแนะนำก่อนหน้านี้ในหัวข้อนี้
Tomalak
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.