5 способов создания ссылок-якорей с отступом сверху. Устранение смещения из-за фиксированного блока (шапка, меню).

Впервые я столкнулся с этим, когда делал на своем сайте выплывающую панель «Поделиться в соц сетях» при скролле поста вниз (попробуйте).

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

А так как сейчас очень популярно делать фиксированные шапки и меню position:fixed, прилепленные к верхней части экрана, то думаю что этот пост будет интересен многим. В нём я рассмотрю несколько вариантов якорей с отступами от верхней границы экрана при переходе по ним.

Для более ясного понимания на все h2-заголовки я добавил заливку.

Пример того, как работает стандартная ссылка-якорь. Если вы попали сюда, кликнув по ссылке, а не просто проскроллили страницу, то скорее всего заголовок у вас оказался полностью скрыт под панелью соц сетей.

Возможно было бы правильнее назвать пост не «5 методов…», а «4 метода…». Потому что это и не метод вовсе, а показательный пример того, как быть не должно, ну да ладно.

Используем псевдоэлемент для добавления отступа перед элементом — :before или :after.

Поддержка браузерами: Chrome конечно же, IE8+, Firefox 3+, Opera 9.25+, Safari 3+.

Замечания:

  • Требуется поддержка браузером CSS псеводоэлементов.
  • Метод не работает корректно, если у элемента есть фон или заливка (наезжает на контент).
  • Не работает корректно, если у элемента есть свойства padding-top или border-top.
#link-B:before {
	display: block;
	content: "";
	height: 55px;
	margin: -55px 0 0;
}

Используем padding для создания отступа и отрицательный margin, чтобы этот же отступ убрать, а точнее — сделать его незаметным для пользователей.

Обратите внимание, что внутренные отступы padding тоже попадают под заливку, то есть, если у вашего элемента будет фон, то он скорее всего наедет на контент перед ним. Для того, чтобы игнорировать padding при добавлении фона на элемент, используйте CSS-свойство background-clip:content-box.

Поддержка браузерами: Chrome конечно же, Firefox 4.0+, Opera 10.6+, Safari 3+.

Замечания:

  • Необходима поддержка браузером background-clip:content-box, но это только в том случае, если вы хотите добавить фон элементу.
  • Некоторые ограничения при использовании margin (в том числе при margin-collapse — это когда из нижнего отступа первого элемента и верхнего отступа второго определяется наибольший, который и становится величиной отступа между этими элементами).
  • Невозможность использования padding-top.
#link-C {
	padding-top: 55px;
	margin-top: -55px;
	-webkit-background-clip: content-box;
	background-clip: content-box;
}

По сути то же самое, что и предыдущий метод, но вместо padding используем border. Что это нам даёт?

  • Теперь вы спокойно можете использовать внутренние отступы padding.
  • Постараюсь выразиться правильно — по идее border — это тот же padding, но только с заливкой и эффектами. Поэтому при использовании фона или заливки элемента нам нужно учесть, чтобы она распростаранялась на сам элемент и на padding, но не на border (ведь он то у нас прозрачный), здесь поможет background-clip:padding-box.
  • Ограничение в использовании border-top, которое однако легко решаемо — смотрите ниже.

Поддержка браузерами: Chrome конечно же, Firefox 1.0+, Opera 10.5+, Safari 3+.

#link-D {
	border-top: 55px solid transparent;
	margin-top: -55px;
	padding: 15px; /* паддинги - без проблем */
	-moz-background-clip: padding;
	-webkit-background-clip: padding-box;
	background-clip: padding-box;
}

Дополнение к предыдущему методу, которое позволит добавить на элемент верхний border. Поддержка браузерами псевдоэлементов и background-clip (только при наличии фона или заливки) обязательна.

Поддержка браузерами: Chrome конечно же, Firefox 3.5+, Opera 10.5+, Safari 3+.

#link-E {
	position: relative; /* важно - для того, чтобы псевдоэлемент позиционировался относительно этого элемента */
	border-top: 55px solid transparent;
	margin-top: -55px;
	-moz-background-clip: padding;
	-webkit-background-clip: padding-box;
	background-clip: padding-box;
}
#link-E:before {
	content: "";
	position: absolute;
	top: -2px; /* равен по модулю толщине border */
	left: 0;
	right: 0;
	border-top: 2px solid #ccc; /* собственно то, ради чего всё затевалось */
}

Миша

В последние годы я долго не знал, что мне делать с сайтом misha.blog, ведь он практически не приносит никакого профита, но недавно я осознал, что моя миссия – способствовать распространению WordPress. Ведь WordPress – это лучший движок для разработки сайтов – как для тех, кто готов использовать заложенную структуру этой CMS, так и для тех, кто предпочитает headless решения.

Сам же я впервые познакомился с WordPress в 2009 году. Организатор WordCamp. Преподаватель в школах Epic Skills и LoftSchool.

Если вам нужна помощь с вашим сайтом или может даже разработка с нуля на WordPress / WooCommerce — пишите. Я и моя команда сделаем вам всё на лучшем уровне.

Комментарии 12

  • Роман 13 ноября 2015 #

    Золотой ты человек!)

    • Роман 21 декабря 2015 #

      Это всё прикольно, но интересней твой фокус в древ.комментариях, где линк вынесен отдельно:

      <a id="comment-####" class="anchored"></a>
      a.anchored {
          position: absolute;
          top: -35px;
          display: block;
      }
      .comment a.anchored {
          top: -65px;
      }
  • Егор 14 ноября 2015 #

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

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

    • Миша 14 ноября 2015 #

      Добрый день!
      Это же прекрасно, что больше обращений стало 🙂

  • Игорь Фёдоров 18 ноября 2015 #

    Привет! Я таким способом делаю:

    /* A smooth scroll */
    $(function() {
    	var menuhe = $('#menu').height(); // высота меню
    	var menu = menuhe+20; // прибавляем 20
    $("area[href*=#],a[href*=#]:not([href=#]):not([href^='#tab']):not([href^='#quicktab']):not([href^='#pane']):not([href *= '#inline'])").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 - menu
    },1500);
    return false;
    }
    }
    });
    });
    • Миша 19 ноября 2015 #

      Привет!

      Это всё круто, просто вся фишка в том, что у меня в статье без js сделано 🙂

  • Николай 24 ноября 2015 #

    Спасибо)

  • Егор 25 ноября 2015 #

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

    Хороший плагин jQuery plugins.compzets.com/animatescroll/ (без http). Он

    • Миша 25 ноября 2015 #

      Здравствуйте!
      Спасибо за ссылку. Ещё scrollTo неплохой jQuery плагин тоже.

  • Нико 11 декабря 2015 #

    спс

  • Александр 9 января 2020 #

    Огонь, второй вариант сработал на "ура"

    • Миша 9 января 2020 #

      Огнище!

Оставить комментарий

Если вы хотите добавить код, не забудьте обернуть его в <pre lang="php"></pre>, в случае несоблюдения этого условия в 99% случаях ваш коммент будет удалён, а автор заблокирован. Печалька.