Фиксированная страница заголовка перекрывает на странице анкеров

StackOverflow https://stackoverflow.com/questions/4086107

  •  28-09-2019
  •  | 
  •  

Вопрос

Если у меня есть заголовок без прокрутки на странице HTML, закреплен на вершине, имея определенную высоту:

Есть ли способ использовать анкер URL ( #fragment Часть) Чтобы прокрутить браузер в определенную точку на странице, но все же уважаю высоту фиксированного элемента без помощи JavaScript?

http://foo.com/#bar
Неправильно (но общее поведение): правильно: + ------------------------------------- + + ---- -------------------------------- + |. Бар ////////////////////////////////////////////// // |. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ------------------------------------- + + ----------------- --------------------- + |. Вот остальная часть текста | |. Бар |. |. ... |. |. |. |. ... |. |. Вот остальная часть текста | |. ... |. |. ... |. + ------------------------------------- + + ----------------- --------------------- +.
Это было полезно?

Решение

У меня такая же проблема. Я решил его, добавив класс в анкерный элемент с высотой топба в виде значения верхнего подвеска.

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

А потом просто CSS:

.anchor { padding-top: 90px; }

Другие советы

Если вы не можете или не хотите устанавливать новый класс, добавьте фиксированную высоту ::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);

Я использую этот подход:

/* 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-sositioning/

Официальный загрузчик принял ответ:

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

Кредиты

Слияние

Лучший способ, которым я обнаружил, чтобы справиться с этим вопросом (замените 65PX с вашим фиксированным высотой элемента):

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

Если вы не любите использовать цель Селектор Вы также можете сделать это таким образом:

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

Примечание. Этот пример не будет работать, если целевой элемент имеет цвет Backgound, который отличается от его родителей. Например:

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

В этом случае зеленый цвет моего целевого элемента будет перезаписать его родительский красный элемент в 65 пикселей. Я не нашел никакого чистого решения CSS, чтобы справиться с этой проблемой, но если у вас нет другого цвета фона, это решение является лучшим.

В то время как некоторые из предложенных решений работают для фрагментов ссылок (= хеш-ссылки) в пределах одна и та же страница (например, ссылка меню, которая прокручивает вниз), я обнаружил, что ни один из них не работал в текущем Chrome, когда вы хотите использовать ссылки на фрагмент с других страниц.

Так что звонит www.mydomain.com/page.html#foo с нуля будет НЕТ Смещение вашей цели в нынешнем хроме с любым из заданных решений CSS или решения JS.

Есть также Отчет об ошибке jquery описывая некоторые детали проблемы.

РЕШЕНИЕ

Единственный вариант, который я нашел до сих пор, что действительно работает в Chrome, это JavaScript, который не вызывается ondombready, но с задержкой.

// 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, то есть сафари, но не в Chrome.

Для Chrome / Safari / Firefox вы можете добавить display: block и используйте отрицательный запас, чтобы компенсировать смещение, как:

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

Смотрите Пример http://codepen.io/swed/pen/rrzbjo.

Вы можете сделать это с jQuery:

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

Вы можете попробовать это:

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

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

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

Установите верхнее значение нагрузки на фактическую высоту заголовка. Это представит небольшой дополнительный разрыв в верхней части вашего заголовка, но он будет видимым только тогда, когда пользователь переходит только на якорь, а затем прокручивается. Я сделал это решение для моего сайта прямо сейчас, но он показывает только небольшую неподвижную полосу в верхней части страницы, ничего не слишком высокого.

Меня устраивает:

HTML ссылка на якорь:

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

HTML-якорь:

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

CSS:

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

Я получил его легко работать с CSS и HTML, используя метод «якорь: перед», упомянутым выше. Я думаю, что это работает лучше всего, потому что он не создает массивных прокладков между вашими делями.

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

Это, похоже, не работает для первого Div на странице, но вы можете противостоять этому, добавив прокладку на этот первый Div.

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

Вот работающая скрипка: http://jsfiddle.net/frphe/24/

Я использую ответ @ 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();
      }
  };
html {
  scroll-padding-top: 70px; /* height of sticky header */
}

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

Это чувствует себя немного взлом для моего пуристового ума, но в качестве решения только в 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>

Я нашел, что должен был использовать оба Mutttenxd.'песок БандабамCSS Solutions вместе, как первый не работал в 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>
...

То, как я нахожусь самым чистым, является следующим:

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

У меня было много проблем со многими ответами, и в других местах, когда мои закладки были заголовками раздела на странице часто задаваемых вопросов, поэтому компенсируя заголовок, не помогал, так как остальная часть контента просто останется там, где это было. Так что я думал, что я опубликовал.

То, что я закончил, был составным из нескольких решений:

  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 Элемент не только скрыт, он по существу рухнул и не прокладывает ваш контент.

Я не могу принимать особые кредиты за это решение, поскольку он исходит от расшагина разных ресурсов, но он лучше всего подходит для меня в моей ситуации.

Вы можете увидеть фактический результат здесь.

В виде CSS Scroll Snap Spec входит в игру, это легко возможно с scroll-margin-top свойство. В настоящее время работает на Chrome и Opera (апрель 2019 г.). Также Safari 11+ следует поддерживать это, но я не смог запустить его на Safari 11. Наверное, мы должны ждать, когда ребята, чтобы исправить его.

Пример кодепена

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>

Минимально навязчивый подход с использованием 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;
});

Назначая класс INCOR-LINK на ссылки, поведение других ссылок (например, аккордеон или элементы управления вкладками) не затрагиваются.

Вопрос не хочет JavaScript, но другой более популярный вопрос закрыт из-за этого, и я не мог ответить там.

Мне нужно что-то, что работает на входящие ссылки, ссылки на странице, и которые могут быть нацелены на 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+

Мне не повезло с ответом, перечисленным выше и в итоге использовали это решение, которое отлично работало ...

Создайте пустой промежуток, где вы хотите установить якорь.

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

Это решение будет работать, даже если разделы имеют разные цветные фоны! Я нашел решение в эта ссылка.

<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/ (Второе окно, под «смещением»)

Вот полное решение 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) {

    });
}

Реализовано с использованием :before Отлично работал, пока мы не поняли, что псевдо-элемент на самом деле охватывал и блокируют события указателя, которые сидели в пределах Псевдоэлементная область. Используя что-то вроде pointer-events: none на :before Или даже непосредственно на якоре не было влиять.

То, что мы оказались, делали анкерную позиционирование абсолютным, а затем настроить его положение, чтобы быть смещением / высотой фиксированной области.

Смещение якоря без блокировки событий указателя

.section-marker {

    position: absolute;
    top: -300px;
}

Значение с этим заключается в том, что мы не блокируем никаких элементов, которые могут попасть в эти 300 пикселей. Недостатком является то, что хватает позиции этого элемента от JavaScript необходимо учитывать, что компенсируется, поэтому любая логика там должна быть отрегулирована.

Вот как я получил его, чтобы наконец-то пойти в правильное место, когда вы нажимаете на навигацию. Я добавил обработчик событий для навигации на навигации. Тогда вы можете просто использовать «Scrollby» для перемещения на смещении.

var offset = 90;

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

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

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

Конечно, вы можете изменить количество разрывов строк в соответствии с вашими потребностями. Это отлично работало для меня, не уверена, что есть какие-то проблемы, хотя я все еще изучаю HTML.

Использовал этот скрипт

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

    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top -140
    }, 1000);
});
// handle hashes when page loads
// <http://stackoverflow.com/a/29853395>
function adjustAnchor() {
  const $anchor = $(':target');
  const fixedElementHeight = $('.navbar-fixed-top').outerHeight();
  if ($anchor.length > 0)
    window.scrollTo(0, $anchor.offset().top - fixedElementHeight);
}
$(window).on('hashchange load', adjustAnchor);
$('body').on('click', "a[href^='#']", function (ev) {
  if (window.location.hash === $(this).attr('href')) {
    ev.preventDefault();
    adjustAnchor();
  }
});

Я использую этот метод, потому что по какой-то причине ни одна из других решений не предложила фактически не сработало для меня. Я обещаю, что попробовал.

section {
   position: relative;
   border-top: 52px solid transparent; /* navbar height +2 */
   margin: -30px 0 0;
   -webkit-background-clip: padding-box;
   -moz-background-clip: padding;
   background-clip: padding-box;
}

section:before {
   content: "";
   position: absolute;
   top: -2px;
   left: 0;
   right: 0;
   border-top: 2px solid transparent;
}

Заменять раздел классом, если вы предпочитаете.

источник: Ссылки на прыжках и позиционирование просмотра просмотра

  • Испытано на Firefox 45 и Chrome 52.
  • Версия Bootstrap: 3.3.7

Для тех, кто не верит мне, я любезно подготовил jsfiddle с решением в нем: РЕШЕНИЕ

CSS CRICK будет обходной путь. Правильное решение, которое будет работать во всем сценарии, может быть реализовано с помощью jQuery.

Ссылаться на https://codepen.io/pikeshmn/pen/mmxedz.

Подход: Мы получаем высоту фиксированной навигации, используя Document.GetelementById («Заголовье»). OffsetheightИ компенсировать свиток к этому значению.

var jump=function(e){  

e.preventDefault();                        //prevent "hard" jump
  var target = $(this).attr("href");       //get the target

      //perform animated scrolling
      $('html,body').animate(
        {
          scrollTop: $(target).offset().top - document.getElementById('header').offsetHeight - 5  //get top-position of target-element and set it as scroll target
        },1000,function()                  //scrolldelay: 1 seconds
        {
          location.hash = target;          //attach the hash (#jumptarget) to the pageurl
        });
      }

  $(document).ready(function()
  {
    $('a[href*="#"]').bind("click", jump); //get all hrefs
    return false;
  });

PS:

  • Он включает в себя хорошую разницу в 5 пикселей между заголовком и целью
  • Эффект прокрутки не является твердым, довольно гладким; Плавная прокрутка
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top