Вопрос по css, html, javascript – смещение html-якоря для корректировки на фиксированный заголовок [duplicate]

944

This question already has an answer here:

Fixed page header overlaps in-page anchors 30 answers

Я пытаюсь навести порядок в работе своих якорей. У меня есть заголовок, который зафиксирован в верхней части страницы, поэтому, когда вы ссылаетесь на якорь в другом месте страницы, страница переходит, так что якорь находится в верхней части страницы, оставляя содержимое за фиксированным заголовком (надеюсь, в этом есть смысл). Мне нужен способ сместить якорь на 25 пикселей от высоты заголовка. Я бы предпочел HTML или CSS, но Javascript также будет приемлемым.

На эту тему есть хорошая статья:css-tricks.com/hash-tag-links-padding J. Bruni
Div обертки показано вstackoverflow.com/questions/1431639/… Хорошо, я думаю, не слишком агрессивно. ron
Связанные с:stackoverflow.com/questions/4086107/… 0fnt
@ 0fnt, на самом деле это дубликат этого поста. Почему это не закрыто? Pacerier
@Pacerier Я думаю, что это требует действий модератора. Я пометил хотя 0fnt

Ваш Ответ

28   ответов
87

FWIW это сработало для меня:

*[id]:before { 
  display: block; 
  content: " "; 
  margin-top: -75px; 
  height: 75px; 
  visibility: hidden; 
}
К вашему сведению: объединено сstackoverflow.com/questions/9047703/…
Я не совсем понимаю, почему это работает, но +1 от меня. Ни один из других не был так прост в реализации или работал, как это. :-)
Я обернул это в медиа-запрос, чтобы он применялся только к средним и большим экранам, где у меня фиксированная навигация.
Это может работать, но оно будет перекрывать содержимое перед заголовком.
Ты да человек! Отличное решение.
133

Я тоже искал решение этой проблемы. В моем случае это было довольно легко.

У меня есть список меню со всеми ссылками:

<ul>
<li><a href="#one">one</a></li>
<li><a href="#two">two</a></li>
<li><a href="#three">three</a></li>
<li><a href="#four">four</a></li>
</ul>

И ниже этого заголовки, куда он должен идти.

<h3>one</h3>
<p>text here</p>

<h3>two</h3>
<p>text here</p>

<h3>three</h3>
<p>text here</p>

<h3>four</h3>
<p>text here</p>

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

Вместо этого я поместил тег span внутри моего тега с правильным идентификатором.

<h3><span id="one"></span>one</h3>

Теперь используйте 2 строки CSS, чтобы правильно расположить их.

h3{ position:relative; }
h3 span{ position:absolute; top:-200px;}

Измените верхнее значение, чтобы оно соответствовало высоте вашего фиксированного заголовка (или более). Теперь я предполагаю, что это будет работать и с другими элементами.

span может быть заменен наa
Это должно получить галочку наверняка.
Это работает очень хорошо и позволяет избежать некоторых проблем, с которыми я сталкиваюсь при использовании других техник, например, при использовании тега h2, который устанавливает верхний отступ.
Мне нравится это решение
Brilliant. Работает отлично. +1
0

Еще одно замечание от @Jan - включить это в фиксированный заголовок #uberbar, который использует jQuery (или MooTools). (http://davidwalsh.name/persistent-header-opacity)

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

CSS:

#uberbar { 
    border-bottom:1px solid #0000cc; 
    position:fixed; 
    top:0; 
    left:0; 
    z-index:2000; 
    width:100%;
}

a.anchor {
    display: block;
    position: relative;
    visibility: hidden;
}

Подходит jQuery (включая настройки как #uberbar, так и привязки):

<script type="text/javascript">
$(document).ready(function() {
    (function() {
        //settings
        var fadeSpeed = 200, fadeTo = 0.85, topDistance = 30;
        var topbarME = function() { $('#uberbar').fadeTo(fadeSpeed,1); }, topbarML = function() { $('#uberbar').fadeTo(fadeSpeed,fadeTo); };
        var inside = false;
        //do
        $(window).scroll(function() {
            position = $(window).scrollTop();
            if(position > topDistance && !inside) {
                //add events
                topbarML();
                $('#uberbar').bind('mouseenter',topbarME);
                $('#uberbar').bind('mouseleave',topbarML);
                inside = true;
            }
            else if (position < topDistance){
                topbarME();
                $('#uberbar').unbind('mouseenter',topbarME);
                $('#uberbar').unbind('mouseleave',topbarML);
                inside = false;
            }
        });
        $('#content').css({'margin-top': $('#uberbar').outerHeight(true)});
        $('a.anchor').css({'top': - $('#uberbar').outerHeight(true)});
    })();
});
</script>

И, наконец, HTML:

<div id="uberbar">
    <!--CONTENT OF FIXED HEADER-->
</div>
....
<div id="content">
    <!--MAIN CONTENT-->
    ....
    <a class="anchor" id="anchor1"></a>
    ....
    <a class="anchor" id="anchor2"></a>
    ....
</div>

Может быть, это полезно для кого-то, кому нравится заголовок #uberbar с замиранием!

9

Для той же проблемы я использовал простое решение: на каждую якорь накладываем верхний слой в 40 пикселей.

К вашему сведению: объединено сstackoverflow.com/questions/9047703/…
Спасибо, это было в основном то, что я в итоге сделал, но мне было интересно, есть ли решение для ситуаций, когда добавление дополнительных отступов может быть неудобным.
21

Мое решение сочетает в себе цели и до селекторов для нашей CMS. Другие методы не учитывают текст в якоре. Отрегулируйте высоту и отрицательное поле до необходимого смещения ...

:target:before {
    content: "";
    display: block;
    height: 180px;
    margin: -180px 0 0;
}
Эти два CSS-решения не сработали для меня с первого взгляда, но в конце концов я это выяснилmight not be compatible with other CSS properties, Добавили обертку, и это решило проблему. Комбинация: target: before с display: block лучше всего подходит для меня.
[Решено] Это решение работает, и я использовал это решение сdisplay: block;, Без специального класса, пустого тега или JavaScript.
27

Для современных браузеров просто добавьте селектор CSS3: target на страницу. Это будет применяться ко всем якорям автоматически.

:target {
    display: block;    
    position: relative;     
    top: -100px;
    visibility: hidden;
}
Селектор: target должен поддерживаться начиная с IE9, но смещение работает только с FF и Chrome и Safari на моем сайте, а не с IE 11.
Когда вы делаете вещи способом HTML5 (и я тоже думаю 4), где вы нацеливаете атрибут id внутри узла, такого как раздел или заголовок, этот способ заставляет элемент отображать перекрывающиеся элементы над ним.
Я думаю, вы могли бы утверждать, что IE не современный браузер. В любом случае, используя CSS-класс вместо селектора: target, он отлично работает и в IE.
Вы могли бы даже сделать:target:before создать скрытый псевдоэлемент, а не скрыть всю цель.
Прячется:target кажется плохой идеей в большинстве случаев. Вы предоставляете любому, кто отправляет кому-либо ссылку на вашу страницу, возможность выбрать любой элемент с идентификатором и удалить его со страницы, которую увидит зритель. С другой стороны, технически подкованные шутники могут хорошо заметить это и решить повеселиться с ним, так же, как когда-то они веселились с возможностью делать ссылки на некоторые новостные сайты с глупыми заголовками в Facebook, манипулируя их URL-адресами. Более серьезно, это может быть дыра в безопасности, если на вашей странице есть что-то вроде «не делитесь этой секретной информацией с кем-либо». сообщение с идентификатором.
2

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

/*jslint browser: true, plusplus: true, regexp: true */

function anchorScroll(fragment) {
    "use strict";
    var amount, ttarget;
    amount = $('header').height();
    ttarget = $('#' + fragment);
    $('html,body').animate({ scrollTop: ttarget.offset().top - amount }, 250);
    return false;
}

function outsideToHash() {
    "use strict";
    var fragment;
    if (window.location.hash) {
        fragment = window.location.hash.substring(1);
        anchorScroll(fragment);
    }
}

function insideToHash(nnode) {
    "use strict";
    var fragment;
    fragment = $(nnode).attr('href').substring(1);
    anchorScroll(fragment);
}

$(document).ready(function () {
    "use strict";
    $("a[href^='#']").bind('click',  function () {insideToHash(this); });
    outsideToHash();
});
О - также это решение предполагает, что для привязки используется атрибут id, а не устаревший атрибут name.
Мне нравится это решение, очень модульное и красиво выполненное. О, я скучаю по дням манипуляций с JQuery и DOM :)
149

Поскольку это проблема презентации, чистое решение CSS было бы идеальным. Однако этот вопрос был задан в 2012 году, и хотя были предложены решения по относительному позиционированию / отрицательной марже, эти подходы кажутся довольно хакерскими, создают потенциальные проблемы потока и не могут динамически реагировать на изменения в DOM / viewport.

Имея это в виду, я считаю, что использование JavaScript являетсяstill (Февраль 2017) лучший подход. Ниже представлено решение vanilla-JS, которое будет реагировать как на щелчки якоря, так и разрешать хэш страницы при загрузке.(См. JSFiddle), Изменить.getFixedOffset() метод, если требуются динамические вычисления. Если вы используете jQuery,вот модифицированное решение с лучшим делегированием событий и плавной прокруткой.

(function(document, history, location) {
  var HISTORY_SUPPORT = !!(history && history.pushState);

  var anchorScrolls = {
    ANCHOR_REGEX: /^#[^ ]+$/,
    OFFSET_HEIGHT_PX: 50,

    /**
     * Establish events, and fix initial scroll position if a hash is provided.
     */
    init: function() {
      this.scrollToCurrent();
      window.addEventListener('hashchange', this.scrollToCurrent.bind(this));
      document.body.addEventListener('click', this.delegateAnchors.bind(this));
    },

    /**
     * Return the offset amount to deduct from the normal scroll position.
     * Modify as appropriate to allow for dynamic calculations
     */
    getFixedOffset: function() {
      return this.OFFSET_HEIGHT_PX;
    },

    /**
     * If the provided href is an anchor which resolves to an element on the
     * page, scroll to it.
     * @param  {String} href
     * @return {Boolean} - Was the href an anchor.
     */
    scrollIfAnchor: function(href, pushToHistory) {
      var match, rect, anchorOffset;

      if(!this.ANCHOR_REGEX.test(href)) {
        return false;
      }

      match = document.getElementById(href.slice(1));

      if(match) {
        rect = match.getBoundingClientRect();
        anchorOffset = window.pageYOffset + rect.top - this.getFixedOffset();
        window.scrollTo(window.pageXOffset, anchorOffset);

        // Add the state to history as-per normal anchor links
        if(HISTORY_SUPPORT && pushToHistory) {
          history.pushState({}, document.title, location.pathname + href);
        }
      }

      return !!match;
    },

    /**
     * Attempt to scroll to the current location's hash.
     */
    scrollToCu,rrent: function() {
      this.scrollIfAnchor(window.location.hash);
    },

    /**
     * If the click event's target was an anchor, fix the scroll position.
     */
    delegateAnchors: function(e) {
      var elem = e.target;

      if(
        elem.nodeName === 'A' &&
        this.scrollIfAnchor(elem.getAttribute('href'), true)
      ) {
        e.preventDefault();
      }
    }
  };

  window.addEventListener(
    'DOMContentLoaded', anchorScrolls.init.bind(anchorScrolls)
  );
})(window.document, window.history, window.location);
прекрасно работает, хотя для jquery 1.7+ используйте $ (& quot; a & quot;). on (& quot; нажмите & quot;, ... вместо $ (& quot; a & quot;). live (& quot; click & quot;, ...
Кроме того, однако, стоит отметить, что это будет мешать другим парам href / id, таким как коллапс, карусель и т. Д. Есть ли простой способ обойти это?
@ tom10 Полагаю, вам просто нужно сделать селектор более конкретным, добавив якоря в черный список, используяa:not(.not-anchor) (или что-то менее смутно названное), а затем убедитесь, что ваши библиотеки коллапса / карусели добавляют эти классы к своим якорям. Если вы используете jQuery UI или Bootstrap, я полагаю, что они добавляют некоторые другие классы, на которые вы могли бы ссылаться.
Хороший комментарий, я обновлю :) - Кстати, это тоже должно быть$("body").on("click", "a"... так как это может потребоваться для якорей, которые добавляются в документ скриптами (поэтому я и использовал.live)
@ tom10 Я добавил несколько условий в тест для# вhref во избежание разрушения и разворота карусели:if(href.indexOf("#") == 0 && (!$(this).data() || this.self == window))
9

Решения с изменением свойства позиции не всегда возможны (это может разрушить макет), поэтому я предлагаю следующее:

HTML:

<a id="top">Anchor</a>

CSS:

#top {
    margin-top: -250px;
    padding-top: 250px;
}

Использовать этот:

<a id="top">&nbsp;</a>

чтобы минимизировать перекрытие, и установите размер шрифта в 1px. Пустой якорь не будет работать в некоторых браузерах.

8

Занимая часть кода из ответапо этой ссылке (автор не указан), вы можете включить хороший эффект плавной прокрутки для привязки, одновременно останавливая его на -60px над привязкой, хорошо вписываясь в панель фиксированной начальной загрузки (требуется jQuery):

$(".dropdown-menu a[href^='#']").on('click', function(e) {
   // prevent default anchor click behavior
   e.preventDefault();

   // animate
   $('html, body').animate({
       scrollTop: $(this.hash).offset().top - 60
     }, 300, function(){
     });
});
Полное решение должно также включать сценарий, в котором пользователь загружает новую страницу с привязкой уже в адресной строке. Я попытался настроить этот код так, чтобы он срабатывал при событии $ (document) .ready, но он все еще прокручивается в неправильном месте в документе. Есть идеи?
спасибо, это решение для пользователей Twitter начальной загрузки
К вашему сведению: объединено сstackoverflow.com/questions/9047703/…
@AdamFriedman вы даже нашли решение для этого конкретного сценария. Я использую библиотеку smoothanchor, к которой я могу добавить смещение, но она также не работает при загрузке страниц с URL. URL # целевой
29

Я столкнулся с подобной проблемой, к сожалению, после реализации всех решений, приведенных выше, я пришел к следующему выводу.

  1. My inner elements had a fragile CSS structure and implementing a position relative / absolute play, was completely breaking the page design.
  2. CSS is not my strong suit.

Я написал эту простую прокрутку js, которая учитывает смещение, вызванное заголовком, и переместил div примерно на 125 пикселей ниже. Пожалуйста, используйте его так, как считаете нужным.

HTML

<div id="#anchor"></div> <!-- #anchor here is the anchor tag which is on your URL -->

JavaScript

 $(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') 
&& location.hostname == this.hostname) {

      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top - 125 //offsets for fixed header
        }, 1000);
        return false;
      }
    }
  });
  //Executed on page load with URL containing an anchor tag.
  if($(location.href.split("#")[1])) {
      var target = $('#'+location.href.split("#")[1]);
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top - 125 //offset height of header here too.
        }, 1000);
        return false;
      }
    }
});

Смживая реализация здесь.

Очень, очень благодарен. Красиво и гладко.
Это хорошее решение и работает хорошо для меня.
Error: User Rate Limit Exceeded
Это работает отлично! Спасибо за код
@Robbiegod, чтобы сместить просто настроить количество пикселей, которое я упомянул,scrollTop: target.offset().top - 125 125 - это то, что сработало для меня. Уточните это в соответствии с вашими потребностями. Было бы здорово, если бы вы могли опубликовать пример с вашей проблемой для получения дополнительных разъяснений.
2

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

То есть иметь HTML, как это ...

<div class="static-navbar">NAVBAR</div>
<div class="scrollable-content">
  <p>Bla bla bla</p>
  <p>Yadda yadda yadda</p>
  <p>Mary had a little lamb</p>
  <h2 id="stuff-i-want-to-link-to">Stuff</h2>
  <p>More nonsense</p>
</div>

... и CSS, как это:

.static-navbar {
  height: 100px;
}
.scrollable-content {
  position: absolute;
  top: 100px;
  bottom: 0;
  overflow-y: scroll;
  width: 100%;
}

Это позволяет достичь желаемого результата простым, не хакерским способом. Единственное различие в поведении между этим и некоторыми из хитроумных хаков CSS, предложенных выше, заключается в том, что полоса прокрутки (в браузерах, которые ее отображают) будет прикреплена к содержимому div, а не ко всей высоте страницы. Вы можете или не можете считать это желательным.

Вот JSFiddle, демонстрирующий это в действии.

Это АБСОЛЮТНО лучшее решение. Это не требует взломов или псевдоклассов. Я также нахожу это на 100% семантическим. По сути, есть часть страницы, которую вы хотите прокрутить, и вы устанавливаете это явно. Кроме того, это полностью решает проблему исчезновения заголовков за навигацией без фона.
Не хакерский, но: (1) совершенно бесполезный вне этого примера, (2) громоздкий для принятия и поддержки, (3) антисемантический и / или оскорбительный css, (4) не интуитивный. Я возьмуclean a:before {...} Решение по этому вопросу в любой день!
Лучший ответ для меня. Я использую это сейчас. Все ответы здесь хакерские. Добавление "перед" псевдоэлемент ко всему неприемлем для меня и потенциально может помешать многим другим элементам CSS, уже использующим & quot; before & quot; псевдоэлемент. Это правильный и чистый способ продолжить.
0

Вы можете достичь этого без идентификатора, используяa[name]:not([href]) css селектор. Это просто ищет ссылки с именем и без ссылки, например<a name="anc1"></a>

Примером правила может быть:

a[name]:not([href]){
    display: block;    
    position: relative;     
    top: -100px;
    visibility: hidden;
}
Обратите внимание, что в HTML5a элемент не имеетname атрибут, так что это не сработает.
-1

Вот решение, которое мы используем на нашем сайте. НастроитьheaderHeight переменная к вашей высоте заголовка. Добавитьjs-scroll Класс к якору, который должен прокручиваться при нажатии.

// SCROLL ON CLICK
// --------------------------------------------------------------------------
$('.js-scroll').click(function(){
    var headerHeight = 60;

    $('html, body').animate({
        scrollTop: $( $.attr(this, 'href') ).offset().top - headerHeight
    }, 500);
    return false;
});
4

Я столкнулся с той же самой проблемой и закончил обрабатывать события щелчка вручную, как:

$('#mynav a').click(() ->
  $('html, body').animate({
      scrollTop: $($(this).attr('href')).offset().top - 40
  }, 200
  return false
)

Прокрутка анимации необязательна, конечно.

К вашему сведению: объединено сstackoverflow.com/questions/9047703/…
301

Я нашел это решение:

<a name="myanchor">
    <h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1>
</a>

Это не создает какого-либо разрыва в контенте, и якорные ссылки работают очень хорошо.

Элемент чуть выше & lt; h1 & gt; не будет кликабельным из-за скрытого отступа / поля. В итоге я использовал решение JQuery от Ian Clack, которое прекрасно работает.
Думаю, я понял это: h2 [id], h3 [id], h4 [id], a [name] {padding-top: XXpx; padding-bottom: XXpx; } Это относится ко всем тегам h2, h3, h4 с идентификаторами, а также к именованным привязкам.
Как заставить его работать с якорями, которые используют идентификаторы элементов, например & lt; h1 id = "smth" & gt; Text & lt; / h1 & gt; ... & lt; a href = & lt; # smth & lt; Link & lt; / a & gt; ?
Работал отлично. Я создал специальный CSS-класс привязки и просто прикрепил его к своим привязкам: & lt; a class = & quot; anchor & quot; Имя = & Quot; Foo & Quot; & GT; & Lt; / а & GT ;. Благодарю.
с навигатором все еще есть сволочь поэтому, если вы прокручиваете страницу вниз, активный навигационный элемент не переключается, пока вы не прокрутите мимо цели привязки.
1025

Вы можете просто использовать CSS без JavaScript.

Дайте вашему якору класс:

<a class="anchor" id="top"></a>

Затем вы можете расположить привязку со смещением выше или ниже того места, где оно фактически отображается на странице, сделав его блок-элементом и установив его относительно. -250px установит якорь на 250px

a.anchor {
    display: block;
    position: relative;
    top: -250px;
    visibility: hidden;
}
Мы не должны больше использовать теги без атрибута href. Вместо этого мы предполагаем использовать теги id в заголовке / section / etc для закрепленного текста. Каково решение тогда?
Это лучший ответ, потому что он не зависит от родительского элемента, положение которого установлено относительно. Спасибо за публикацию этого.
@harpo: хорошая идея, но она не работает. Пробовал в Chrome 40.
Если вы хотите, чтобы это работало для видимых элементов, вы также можете использовать псевдоэлемент, а.thing-with-anchor:before { content: ''; display: block; position: relative; width: 0; height: 5em; margin-top: -5em }  Блок дисплея и относительное положение имеют важное значение.
Любите ваше решение! Кажется, не работает с IE7. Во всяком случае, я планирую игнорировать пользователей IE7 отныне ...
81

Чистое решение CSS, вдохновленное Александром Савиным:

a[name] {
  padding-top: 40px;
  margin-top: -40px;
  display: inline-block; /* required for webkit browsers */
}

При желании вы можете добавить следующее, если цель все еще находится за пределами экрана:

  vertical-align: top;
селектор [имя] не должен быть затронут ссылками
Для меня & quot; отображение: встроенный блок; & quot; полностью сломал функционал в Chrome (все ссылки стали не кликабельными).
@ Asrail Для меня это не сработало без него
Я только что попробовал на Chrome и дисплей inline-block не требовался.
К вашему сведению: объединено сstackoverflow.com/questions/9047703/…
2

Вышеприведенные методы не очень хорошо работают, если якорь является элементом таблицы или внутри таблицы (строки или ячейки).

Я должен был использовать JavaScript и привязать к окнуhashchange событие, чтобы обойти это (демонстрация):

function moveUnderNav() {
    var $el, h = window.location.hash;
    if (h) {
        $el = $(h);
        if ($el.length && $el.closest('table').length) {
            $('body').scrollTop( $el.closest('table, tr').position().top - 26 );
        }
    }
}

$(window)
    .load(function () {
        moveUnderNav();
    })
    .on('hashchange', function () {
        moveUnderNav();
    });

* Обратите вниманиеhashchange Событие доступно не во всех браузерах.

0

как насчет скрытых тегов span со связанными идентификаторами, которые обеспечивают высоту панели навигации:

#head1 {
  padding-top: 60px;
  height: 0px;
  visibility: hidden;
}


<span class="head1">somecontent</span>
<h5 id="headline1">This Headline is not obscured</h5>

вот скрипкаhttp://jsfiddle.net/N6f2f/7

К вашему сведению: объединено сstackoverflow.com/questions/9047703/…
0

Я добавил 40px-height.vspace элемент, удерживающий якорь перед каждым из моихh1 элементы.

<div class="vspace" id="gherkin"></div>
<div class="page-header">
  <h1>Gherkin</h1>
</div>

В CSS:

.vspace { height: 40px;}

Это работает отлично, и пространство не задыхается.

К вашему сведению: объединено сstackoverflow.com/questions/9047703/…
0

Вы также можете добавить якорь с помощью следующего атрибута:

(text-indent:-99999px;)
visibility: hidden;
position:absolute;
top:-80px;    

и дать родительскому контейнеру относительную позицию.

Работает идеально для меня.

К вашему сведению: объединено сstackoverflow.com/questions/9047703/…
26

You can do it without js and without altering html. It´s css-only.

a[id]:before {
    content:"";
    display:block;
    height:50px;
    margin:-30px 0 0;
}

Это добавит псевдоэлемент перед каждым a-тегом с идентификатором. Настройте значения в соответствии с высотой вашего заголовка.

Если вы когда-нибудь задумывались, почему он не работает для вас, проверьте, не имеет ли родительский элементborder или жеpadding.
Error: User Rate Limit Exceeded
Интересная идея, но обратите внимание, что это портит дисплей, если у вас есть видимые ссылки сidError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded:target[id]:beforeError: User Rate Limit Exceeded
[id]: before можно изменить на что-то другое, например, div [name]: before
0

Добавляя к ответу Зиава (спасибо Александру Савину), мне нужно использовать старую школу<a name="...">...</a> как мы используем<div id="...">...</div> для другой цели в нашем коде. У меня были некоторые проблемы с отображением при использованииdisplay: inline-block - первая строка каждого<p> Элемент оказался слегка правосторонним (в браузерах Webkit и Firefox). Я в конечном итоге пытался другойdisplay ценности иdisplay: table-caption отлично работает для меня

.anchor {
  padding-top: 60px;
  margin-top: -60px;
  display: table-caption;
}
Error: User Rate Limit Exceededstackoverflow.com/questions/9047703/…
1

Я сталкиваюсь с этой проблемой на веб-сайте TYPO3, где все "Элементы содержимого" обернуты чем-то вроде:

<div id="c1234" class="contentElement">...</div>

и я изменил рендеринг, так что он рендерит так:

<div id="c1234" class="anchor"></div>
<div class="contentElement">...</div>

И этот CSS:

.anchor{
    position: relative;
    top: -50px;
}

Фиксированная верхняя панель имеет высоту 40px, теперь якоря снова работают и начинают 10px под верхней панелью.

Единственным недостатком этой техники является то, что вы больше не можете использовать:target.

На самом деле вы можете использовать: цель так:.anchor:target+div
10

Как говорит @moeffju, это может бытьдостигается с помощью CSS, Проблема, с которой я столкнулся (которую я удивлен, которую я не видел, обсуждалась) заключается в уловке наложения предыдущих элементов с отступом или прозрачной рамкой, предотвращающей действия при наведении и щелчке в нижней части этих разделов, поскольку следующий пункт выше в г-го порядка.

Лучшее решение, которое я нашел, - поместить содержимое раздела вdiv это вz-index: 1:

// Apply to elements that serve as anchors
.offset-anchor {
  border-top: 75px solid transparent;
  margin: -75px 0 0;
  -webkit-background-clip: padding-box;
  -moz-background-clip: padding;
  background-clip: padding-box;
}

// Because offset-anchor causes sections to overlap the bottom of previous ones,
// we need to put content higher so links aren't blocked by the transparent border.
.container {
  position: relative;
  z-index: 1;
}
33

Это берет много элементов из предыдущих ответов и объединяет в крошечную (уменьшенную на 194 байта) анонимную функцию jQuery. регулироватьfixedElementHeight для высоты вашего меню или блокирующего элемента.

    (function($, window) {
        var adjustAnchor = function() {

            var $anchor = $(':target'),
                    fixedElementHeight = 100;

            if ($anchor.length > 0) {

                $('html, body')
                    .stop()
                    .animate({
                        scrollTop: $anchor.offset().top - fixedElementHeight
                    }, 200);

            }

        };

        $(window).on('hashchange load', function() {
            adjustAnchor();
        });

    })(jQuery, window);

Если вам не нравится анимация, замените

$('html, body')
     .stop()
     .animate({
         scrollTop: $anchor.offset().top - fixedElementHeight
     }, 200);

с:

window.scrollTo(0, $anchor.offset().top - fixedElementHeight);

Uglified версия:

 !function(o,n){var t=function(){var n=o(":target"),t=100;n.length>0&&o("html, body").stop().animate({scrollTop:n.offset().top-t},200)};o(n).on("hashchange load",function(){t()})}(jQuery,window);
Это решило мою проблему. Может быть, стоит поставить это замечание в ответ.
@ Crono1985 Ваш документ HTML 4 или 5? В 4 идентификаторы имели более строгий список символов, поэтому они могут не регистрироваться в качестве допустимых целей. Далее, вы используете идентификатор или имя? В HTML5 ID является допустимым якорем для всех тегов, но имя может использоваться только в тегах ссылок.
Очень хорошо! Спасибо! Единственная проблема, она не работает надежно, если следовать по ссылке с фрагментом / хэшем (я имею в виду якорь some-page #). По крайней мере, на Chromium 45.0.2454.101 и Firefox. Я не уверен, что это можно исправить, хотя.
Это решение действительно помогло мне, но оно как-то не работает последовательно в IE9-11. Иногда это работает, некоторые другие щелчки это не делает (позиция прокрутки остается в позиции привязки). У меня совершенно нет идей, что может вызвать проблему.
@MajesticRa Одна сложная проблема - это порядок операций в событиях загрузки или прокрутки. Если ваша страница корректирует макет после загрузки или прокрутки страницы (например, сужение заголовка), вычисление смещения: target может быть неправильным.
-1

Решение @ AlexanderSavin отлично работает вWebKit браузеры для меня.

Мне дополнительно пришлось использовать: цель псевдокласс, который применяет стиль к выбранной привязке для настройки заполненияFF, Opera & Амп;IE9:

a:target {
  padding-top: 40px
}

Note that this style is not for Chrome / Safari so you'll probably have to use css-hacks, conditional comments etc.

Также я хотел бы отметить, что решение Александра работает из-за того, что целевой элементinline, Если вам не нужна ссылка, вы можете просто изменитьdisplay имущество:

<div id="myanchor" style="display: inline">
   <h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1>
</div>
мои элементы навигации ссылаются на элементы h2, которые все отображают: блок. Я использую Chrome, и мне не нужно было устанавливать h2 'inline или inline-block.
К вашему сведению: объединено сstackoverflow.com/questions/9047703/…
@ the0ther Я имел в виду элемент обертки, а не заголовки. Также испытывают трудности с представлением вашей разметки на основе ваших слов.

Похожие вопросы