Заголовок виправленої сторінки перекривається внутрішніми якорями


358

Якщо у мене на заголовку HTML, закріпленому вгорі, заголовок, що не прокручується, має визначену висоту:

Чи є спосіб використання якоря URL ( #fragmentчастини), щоб браузер прокручувався до певної точки сторінки, але все-таки дотримувався висоти нерухомого елемента без допомоги JavaScript ?

http://foo.com/#bar
НЕПРАВНО (але загальна поведінка): ПРАВИЛЬНО:
+ --------------------------------- + + -------------- ------------------- +
| БАР ///////////////////// заголовок | | //////////////////////// заголовок |
+ --------------------------------- + + -------------- ------------------- +
| Ось решта Тексту | | БАР |
| ... | | |
| ... | | Ось решта Тексту |
| ... | | ... |
+ --------------------------------- + + -------------- ------------------- +



3
@ax ТАК, це найкраща відповідь. Також перевірте 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; }
Флен

Я шукаю рішення, яке * працює для якорів, що надходять із тієї самої сторінки чи іншої сторінки, * і яка коригує натискання клавіш на сторінку, щоб вміст не було відсікано заголовок, * і що дозволяє футеру сиб-діву прокрутіть вміст-div. Ще не знайшли рішення! Але я мушу сказати, я думаю, що правильний спосіб орієнтував би на весь вміст, а не на кожен окремий якір. stackoverflow.com/questions/51070758 / ...
Johny , чому

@ax. CSS-tricks.com має набагато більш нову статтю про scroll-padding-topтут: css-tricks.com / ... Відповідного відповіді: stackoverflow.com/a/56467997/247696
Флімм

Відповіді:


167

У мене була така ж проблема. Я вирішив це, додавши клас елементу якоря з висотою верхньої панелі як величиною padding-top.

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

А потім просто css:

.anchor { padding-top: 90px; }

19
@ Томалак Будьте в курсі, що це рішення робить посилання всередині області прокладки не можна натискати. Для виправлення цього необхідно використовувати z-індекс та встановити значення посилань вище, ніж якір. Пам'ятайте, що у верхній панелі повинно бути найвище значення z-індексу, тому вміст сторінки не пливе на верхній панелі під час прокрутки.
MutttenXd

Не працював у Chrome v28 через помилку з фіксованою позицією WebKit, яка призводила до зникнення заголовка. Ця відповідь зробила трюк у моєму випадку.
Knickedi

2
MuttenXd .. ти мій герой. У мене на веб-сайті були дивні проблеми з нефункціональним зв’язком (не пов'язані з якорями), зводили мене з розуму. Ваш коментар, який не можна натискати, справді допоміг. Я завдячую вам великим!
zipzit

9
Як запропоновано у відповіді Роя Шоа, додайте, 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 */
}

Або прокрутіть сторінку щодо :targetjQuery:

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

30
Мені дуже подобається ваше рішення. Це найчистіше рішення, яке я знайшов.
Ітай Грудев

5
Це рішення, яке працювало для мене ідеально, не заповнюючи нічого іншого в макеті сторінки.
Джеймі Карл

2
CSS-рішення має проблеми при використанні зі списком у WebKit. Дивіться: stackoverflow.com/questions/39547773/…
Мерт С. Каплан

14
Він не працюватиме, якщо ціль має верхню підкладку або облямівку, оскільки вона покладається на краху-краху.
крулик

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
scavenger

Протестовано це на останньому Firefox (55.0.3 на ПК), і він працює зараз. :-)
RachieVee

46

Офіційний відповідь на завантаження:

*[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/…
Мерт С. Каплан

Зауважте, що це не буде працювати, якщо у нього є цільовий елемент display: flex;або padding-top. <a name="my_link">{leave this empty}</a>У цих випадках використовуйте виділений елемент якоря (як ).
WoodrowShigeru

Це не спрацює, якщо цільовим елементом є <tr>
Іван Гусєв,

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

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



Працює для мене. Я переходжу до якоря з іншої сторінки. Інші не працювали. Дякую!
davidloper

1
Це не працює для прокрутки всієї сторінки в Edge та Safari ( bugs.webkit.org/show_bug.cgi?id=179379 ).
Юліуш Gonera

1
Спаситель! Простий, на точку. Жодне з інших рішень не працювало для мене, тому що я використовую display: flex. Дякую тоні, було так неприємно пробувати всі рішення.
Priya Payyavula

Це КРАСИВЕ рішення, я використовував поведінку прокрутки: гладко! Важливо; також ходити на якір, дуже просто в двох рядках коду
yehanny

30

Найкращий спосіб вирішити цю проблему - замінити 65 пікселів на вашу фіксовану висоту елемента:

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>

у цьому випадку зелений колір мого цільового елемента замінить його батьківський червоний елемент у 65 пікселів. Я не знайшов жодного чистого CSS-рішення для вирішення цієї проблеми, але якщо у вас немає іншого кольору фону, це рішення є найкращим.


2
З усіх відповідей, це єдиний, хто працював на мене!
Хав'єр Аріас

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. Насправді в цьому і полягає вся суть використання OnDomReady. Тому я здогадуюсь, що версія тайм-ауту - це стабільний шлях.
Jpsy

Ця відповідь була єдиною, яка працювала на зовнішні посилання. Однак для мене це не працює, коли посилання викликається на одній сторінці :( Будь-які ідеї?
Аугусто Самаме Баррієнтос

@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
Це досить мило. Будемо сподіватися, що вона буде прийнята ширше!
Томалак

У чому різниця між scroll-padding-topі scroll-margin-top?
Flimm

scroll-margin-topцей випадок використання, на жаль, не реалізований у Safari 11-13: bugs.webkit.org/show_bug.cgi?id=189265
fabb

У Сафарі його називають scroll-snap-margin-top: caniuse.com/#search=scroll-margin-top
Му-Цун Цай

@ Mu-TsunTsai Це трохи складніше. Це дійсно існує на Safari, але це не працює з поведінкою прокрутки до фрагменту. Дивіться мій коментар у випуску даних щодо веб-переглядача: github.com/mdn/browser-compat-data/isissue/…
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"
Мерт С. Каплан

@ MertS.Kaplan ".target" - клас "ціль".
webvitaly

7

Щойно виявив ще одне чисте рішення CSS, яке працювало як шарм для мене!

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

Знайдено на цьому сайті !


2
Кілька інші виявили це рішення , перш ніж, побачити відповіді на сторінці 1, наприклад stackoverflow.com/a/56467997/18771
Томалак

Вибачте, не помітили! Дякую!
Джамаве

Це не працює для прокрутки всієї сторінки в Edge та Safari ( bugs.webkit.org/show_bug.cgi?id=179379 ).
Юліуш Gonera

5

Ви можете спробувати це:

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

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

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

Встановіть значення верхньої колодки на фактичну висоту заголовка. Це введе невеликий додатковий проміжок у верхній частині заголовка, але він буде помітний лише тоді, коли користувач стрибне на якір і потім прокрутить вгору. Я вирішив це рішення для свого сайту зараз, але він показує лише невелику фіксовану смужку вгорі сторінки, нічого надто високого.


Mh. Непогано, але все-таки досить злому (і не працює в IE, на жаль).
Томалак

5

У мене це легко працює з CSS та HTML, використовуючи згаданий вище метод "anchor: before". Я думаю, що це працює найкраще, тому що це не створює масивного прокладки між вашими дівами.

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

Здається, це не працює для першого діла на сторінці, але ви можете протидіяти цьому, додаючи до цього першого діва.

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

Ось робоча загадка: http://jsfiddle.net/FRpHE/24/


5

Це працює для мене:

Посилання HTML на прив’язку:

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

HTML-якір:

<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 попросив не використовувати javascript.
Джуліо Каччін

Працює із зовнішніми посиланнями, але не зі внутрішніми посиланнями.
оснастка

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
Дуже дякую вам за обмін! Стара, як нитка, все ще не здається одним канонічним рішенням цієї проблеми.
Томалак

1
+ SteveCinq Ви подумали - я стикався з тими ж проблемами, коли спільні рішення працювали не так, як передбачалося. Додавання в <span>анкера в прольоті, а також додавання прокладки і запасу працювали на мене. Дякуємо, що знайшли час, щоб подати цю відповідь, незважаючи на вік теми!
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
Це не той самий метод, який показав Гійом Ле Мієр та кілька інших у цій темі?
Томалак

Це дуже схоже, але я вважаю, що це легше зрозуміти і більш детальну відповідь з ще більш поглибленим посиланням на зовнішнє джерело.
Метт Андервуд

Це те саме рішення, але я можу зрозуміти і легко дотримуватися цього. Інші не дали мені достатньо інформації.
MacroMan

3

Мій пуристський розум виглядає дещо хитким, але як рішення, що стосується лише css, ви можете додати прокладки до активного якірного елемента, використовуючи :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
Це зовсім не хакі! Приємне рішення.
Томалак

3

Я знайшов , що я повинен був використовувати як MutttenXd «s і Badabam » CSS рішення s разом, як перший не працює в 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:

Посилання:

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

Присвоюючи клас прив’язки до посилань, поведінка інших посилань (наприклад, акордеона або елементів управління) не впливає.

Питання не хоче JavaScript, але інше більш популярне питання закрите через це, і я не міг відповісти на нього.


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Дозволяє посилання в «області відступу» вище фрагмент-мішені до сих пір бути інтерактивними, так прокоментувало @MuttenXd своєї відповіді

Я ще не знайшов проблему в IE 11, Edge 15+, Chrome 38+, FF 52+ або Safari 9.1+


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

Цей код повинен зробити свою справу. Замініть 45 px на висоту заголовка.

EDIT: Якщо використання jQuery - це варіант, я також успішно використовував jQuery.localScroll із встановленим значенням зміщення. Параметр зміщення - це частина jQuery.scrollTo, на якій будується jQuery.localScroll. Демонстраційна версія доступна тут: http://demos.flesler.com/jquery/scrollTo/ (друге вікно, під "компенсацією")


це рішення справді працює, але воно не є бронезахисним, і воно вимагає багато тонкого налаштування для різних браузерів :( добре спробуйте. Я шукаю рішення без додаткової розмітки.
Vlad saling

Соромно, що це так безладно, що ви не можете просто використовувати посвідчення особи. Дуже хотів би знайти рішення, я пробував усілякі речі.
теоретиза

1

Ось повне рішення jquery, яке буде працювати в 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-рішень на цій сторінці та на stackoverflow.com/questions/10732690/… та на stackoverflow.com/questions/10732690/…, але вони не використовувались через мої вимоги. Сторінка - це сторінка з поширеними питаннями, на якій можна розмістити як на сторінці, так і поза нею, тому може бути багато порожніх плям. Продовження в наступному коментарі ....
Джеффрі Саймон

1
Щоб змусити мене працювати, ось незначні зміни: (1) змінити "<=" у рядку href.index на "<", щоб дозволити візуальну навігацію на сторінці; (2) змінити "a.navigation", який повинен був бути "#faq a" для мого використання; (3) змінити var зTop = 250 на потрійний на основі window.innerWidth для відмінностей у мобільному та робочому столі; (4) змінити 400 в анімації на 1, оскільки анімація не бажана і 0 не працює; (5) додати if ($ ('my-page-selector')) Довжина перед викликом до offSetScrollFromLocation в анонімній функції, щоб запобігти непотрібним дзвінкам на сторінках, де не потрібно.
Jeffrey Simon

1

Реалізований з використанням :beforeпрацював чудово, поки ми не зрозуміли, що псевдоелемент насправді охоплює та блокує вказівні події, які сиділи в зоні елемента псевдо. Використовуючи що - щось на зразок pointer-events: noneна :beforeабо навіть безпосередньо на якір вже не впливає.

Що ми в кінцевому підсумку робимо, робимо позиціонування якоря абсолютним, а потім коригуємо його положення, щоб бути зміщенням / висотою фіксованої області.

Зсув якір без блокування подій вказівника

.section-marker {

    position: absolute;
    top: -300px;
}

Цінність цього полягає в тому, що ми не блокуємо жодних елементів, які можуть потрапити в ці 300 пікселів. Мінус полягає в тому, що для захоплення позиції цього елемента з Javascript потрібно враховувати це зміщення, тому будь-яка логіка там повинна була коригуватися.


1

Ось як я отримав це, щоб, нарешті, перейти до потрібного місця, коли натиснути на навігацію. Я додав обробник подій для натискань навігації. Тоді ви можете просто використовувати "scrollBy", щоб рухатись на зміщення.

var offset = 90;

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

2
Вирішує проблему, але не частину "без допомоги Javascript" ...
Томалак

1

Я створив div з кількома перервами рядків і дав цей ідентифікатор, а потім поклав код, який хотів показати під ним. Тоді посилання переведе вас на пробіл над зображенням, і заголовок більше не буде в дорозі:

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

Звичайно, ви можете змінити кількість розривів рядків відповідно до ваших потреб. Це прекрасно працювало для мене, не впевнений, чи є якісь проблеми, хоча я все ще вивчаю HTML.


Прагматичний, але є і зворотний бік - він працює лише для першого заголовка на сторінці. Якщо заголовків буде більше, ви почнете бачити великі прогалини в тексті через <br>теги перед кожним заголовком.
Томалак

1

Використовували цей сценарій

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

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

Спробуйте пояснити, чому ви думаєте, що цей сценарій вирішить проблему
Алі Канат

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.