IT

고정 헤더에 대해 조정하기 위해 html 앵커 오프셋

itgroup 2023. 1. 15. 17:04
반응형

고정 헤더에 대해 조정하기 위해 html 앵커 오프셋

나는 내 앵커들이 일하는 방식을 정리하려고 노력하고 있다.페이지 맨 위에 고정된 헤더가 있기 때문에 페이지의 다른 곳에 있는 앵커에 링크하면 페이지가 점프하여 앵커가 페이지 맨 위에 위치하도록 하고 고정 헤더 뒤에 내용을 남겨둡니다(이것이 타당하기를 바랍니다).닻을 헤더 높이에서 25px만큼 상쇄할 방법이 필요합니다.HTML이나 CSS를 선호하지만 Javascript도 괜찮습니다.

javascript 없이 CSS를 사용할 수 있습니다.

앵커에게 클래스 부여:

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

그런 다음 블록 요소로 만들고 상대적으로 배치함으로써 페이지에 실제로 표시되는 위치보다 높거나 낮은 오프셋을 앵커를 배치할 수 있습니다. -250px는 앵커를 250px 위로 배치합니다.

a.anchor {
    display: block;
    position: relative;
    top: -250px;
    visibility: hidden;
}

다음 해결책을 찾았습니다.

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

콘텐츠에 공백이 생기지 않고 앵커링크가 잘 작동합니다.

저도 해결책을 찾고 있었어요.제 경우엔, 꽤 쉬웠어요.

모든 링크가 포함된 목록 메뉴가 있습니다.

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

페이지 상단에 고정 메뉴가 있기 때문에 메뉴 뒤에 있기 때문에 태그로 이동할 수 없습니다.

대신 적절한 ID를 가진 스판 태그를 태그 안에 넣었습니다.

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

이제 2줄의 CSS를 사용하여 올바르게 배치합니다.

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

고정 헤더 높이(또는 그 이상)와 일치하도록 상단 값을 변경합니다.다른 요소에서도 사용할 수 있다고 생각합니다.

WWIW 이게 나한테는 통했어:

[id]::before {
  content: '';
  display: block;
  height:      75px;
  margin-top: -75px;
  visibility: hidden;
}

이것은 프레젠테이션의 문제이기 때문에 순수한 CSS 솔루션이 이상적입니다.그러나, 이 질문은 2012년에 제기되었고, 상대적인 포지셔닝/부정적인 마진 솔루션이 제안되었지만, 이러한 접근방식은 다소 진부한 것으로 보이며, 잠재적인 흐름 문제를 발생시키며, DOM/뷰포트의 변화에 동적으로 대응할 수 없다.

그런 의미에서 JavaScript를 사용하는 것이 여전히 (2017년 2월) 최선의 접근법이라고 생각합니다.다음은 앵커 클릭과 로드 시 페이지 해시를 모두 해결하는 바닐라-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.
     */
    scrollToCurrent: 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);

Alexander Savin에서 영감을 얻은 순수한 css 솔루션:

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

타겟이 아직 화면에 표시되지 않는 경우는, 다음의 항목을 추가할 수도 있습니다.

  vertical-align: top;

이 솔루션은 CMS의 타깃과 셀렉터 전을 조합합니다.다른 기술은 앵커 내의 텍스트를 고려하지 않습니다.높이와 음의 여백을 필요한 오프셋으로 조정...

:target::before {
    content: '';
    display: block;
    height:      180px;
    margin-top: -180px;
}

이는 이전 응답에서 많은 요소를 가져와 아주 작은(194바이트 최소화) 익명 jQuery 함수로 결합됩니다.고정 요소 조정메뉴 또는 차단 요소의 높이에 대한 높이입니다.

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

Ugliated 버전:

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

최신 브라우저의 경우 페이지에 CSS3 : target 실렉터를 추가합니다.이것은 모든 앵커에 자동으로 적용됩니다.

:target {
    display: block;    
    position: relative;     
    top: -100px;
    visibility: hidden;
}

js나 html을 변경하지 않고 실행할 수 있습니다.css 전용입니다.

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

그러면 ID가 있는 모든 a-tag 앞에 의사 요소가 추가됩니다.헤더 높이에 맞게 값을 조정합니다.

저도 같은 문제에 직면해 있었습니다만, 유감스럽게도 위의 모든 솔루션을 실장하고 나서, 다음과 같은 결론에 도달했습니다.

  1. 나의 내부 요소는 취약한 CSS 구조를 가지고 있었고 상대/절대 플레이 포지션을 구현하여 페이지 디자인을 완전히 무너뜨리고 있었다.
  2. CSS는 내 강점이 아니다.

헤더에 의한 오프셋을 설명하는 간단한 스크롤 js를 작성하여 125픽셀 정도 아래 div 위치를 변경했습니다.마음에 드는 대로 사용해 주세요.

HTML

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

자바스크립트

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

실장은 이쪽에서 보실 수 있습니다.

같은 문제에 대해, 저는 쉬운 해결책을 사용했습니다: 각 앵커에 40px의 패딩 탑을 장착합니다.

@moeffju에서 알 수 있듯이 이는 CSS를 통해 달성할 수 있습니다.제가 마주친 문제(논의하지 않은 것이 놀랍지만)는 이전 요소를 패딩이나 투명한 테두리와 겹쳐서 다음 항목이 z 순서로 상위 항목이기 때문에 이러한 섹션의 맨 아래에 있는 호버 앤 클릭 액션을 방지하는 기술입니다.

가장 을 가가에 넣는 이다.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;
}

위치 속성이 변경되는 솔루션이 항상 가능한 것은 아니기 때문에(레이아웃이 파괴될 수 있습니다) 다음을 권장합니다.

HTML:

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

CSS:

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

사용방법:

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

중복을 최소화하고 글꼴 크기를 1px로 설정합니다.일부 브라우저에서는 빈 앵커가 작동하지 않습니다.

링크에서 주어진 응답(작성자가 지정되지 않음)에서 코드 일부를 빌리면 앵커에 적절한 스무스 스크롤 효과를 포함시키면서 앵커 위의 -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(){
     });
});

위의 방법은 앵커가 표 요소이거나 표(행 또는 셀) 내에 있는 경우에는 잘 작동하지 않습니다.

하여 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();
    });

* 주의: 해시 변경 이벤트는 일부 브라우저에서 사용할 수 없습니다.

ID를 할 수 .a[name]:not([href]) selector가 없는 이것은 단순히 이름이 있고 href가 없는 링크를 찾습니다. <a name="anc1"></a>

예를 들어 다음과 같은 규칙이 있습니다.

a[name]:not([href]){
    display: block;    
    position: relative;     
    top: -100px;
    visibility: hidden;
}

페이지 본문 전체가 스크롤 가능한 상태에서 페이지의 나머지 콘텐츠에 의해 언더랩되는 고정 위치 내비게이션을 사용하는 대신 스크롤 불가능한 본문을 정적 내비게이션을 사용하여 페이지 내용을 아래 스크롤 가능한 절대 위치에 두도록 하십시오.

즉, 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%;
}

다만, 이 어프로치에는 큰 단점이 있습니다.즉, 페이지 헤더의 요소가 초점을 맞추고 있는 동안, 유저는 키보드를 사용해 페이지를 스크롤 할 수 없습니다(위 화살표와 아래 화살표, 페이지 업과 페이지 다운 키 등).

여기 JSFiddle이 이를 실천하고 있습니다.

이는 Shouvik의 답변에서 영감을 얻은 것으로, Shouvik의 개념과 동일하며, 고정된 헤더의 크기만 하드 코딩되지 않습니다.고정 헤더가 첫 번째 헤더노드에 있는 한, 이것은 「그냥 기능합니다」

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

저는 모든 "콘텐츠 요소"가 다음과 같은 내용으로 포장된 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

지아브의 답변에 덧붙여 (알렉산더 사빈 덕분에) 구식인<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;
}

40px를 했습니다..vspace의 내 에 닻을 요소h1★★★★★★★★★★★★★★★★★★.

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

CSS의 경우:

.vspace { height: 40px;}

작동도 잘 되고 공간도 막히지 않습니다.

링크 가능한 ID를 가진 숨겨진 스팬 태그는 다음과 같이 네비게이션바의 높이를 나타냅니다.

#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

다음 특성을 사용하여 앵커를 추가할 수도 있습니다.

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

부모 컨테이너에 상대 위치를 지정합니다.

나한테는 딱 맞아.

@Jan의 훌륭한 답변에 대한 또 다른 반전은 이것을 jQuery(또는 MoTools)를 사용하는 #uberbar 고정 헤더에 통합하는 것입니다.(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 페이딩 Dixed 헤더를 좋아하는 사람에게 도움이 될 수 있습니다!

@은 @AlexanderSavin에서 매우 WebKit이치노

또한 패딩을 조정하기 위해 선택한 앵커에 스타일을 적용하는 :target pseudo-class를 사용해야 했습니다.FF,Opera&IE9:

a:target {
  padding-top: 40px
}

은 '아주 좋다'가 .ChromeSafaricss-hacks, 조건부 댓글 등을 사용해야 할 것 같습니다.

또한 알렉산더의 솔루션이 효과가 있다는 것도 주목하고 싶습니다.inline 않는 할 수 display★★★★

<div id="myanchor" style="display: inline">
   <h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1>
</div>

델이 사이트에서 사용하는 솔루션은 다음과 같습니다. 조정하다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;
});

같은 문제가 발생하여 클릭 이벤트를 수동으로 처리하게 되었습니다.예를 들어보면 다음과 같습니다.

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

물론 스크롤 애니메이션은 옵션입니다.

언급URL : https://stackoverflow.com/questions/10732690/offsetting-an-html-anchor-to-adjust-for-fixed-header

반응형