Fixed page header overlaps in-page anchors

前端 未结 30 2830
逝去的感伤
逝去的感伤 2020-11-22 00:25

If I have a non-scrolling header in an HTML page, fixed to the top, having a defined height:

Is there a way to use the URL anchor (the #fragment part) t

相关标签:
30条回答
  • 2020-11-22 00:57

    I think this approach is more useful:

    <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;
    }
    
    0 讨论(0)
  • 2020-11-22 00:58

    If you can’t or don’t want to set a new class, add a fixed-height ::before pseudo-element to the :target pseudo-class in CSS:

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

    Or scroll the page relative to :target with jQuery:

    var offset = $(':target').offset();
    var scrollto = offset.top - 60; // minus fixed header height
    $('html, body').animate({scrollTop:scrollto}, 0);
    
    0 讨论(0)
  • 2020-11-22 00:58

    I'm using @Jpsy's answer, but for performance reasons I'm only setting the timer if the hash is present in the 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();
          }
      };
    
    0 讨论(0)
  • 2020-11-22 00:58

    Implemented using :before worked great until we realized that the pseudo element was actually covering and blocking pointer events that sat within the pseudo element's area. Using something like pointer-events: none on the :before or even directly on the anchor had no affect.

    What we ended up doing was making the anchor's positioning absolute and then adjusting it's position to be the offset/height of the fixed area.

    Offset Anchor without Blocking Pointer Events

    .section-marker {
    
        position: absolute;
        top: -300px;
    }
    

    The value with this is that we're not blocking any elements that might fall within those 300px. The downside is that grabbing that element's position from Javascript needs to take into account that offset so any logic there had to be adjusted.

    0 讨论(0)
  • 2020-11-22 00:59

    You can do this with jQuery:

    var offset = $('.target').offset();
    var scrollto = offset.top - 50; // fixed_top_bar_height = 50px
    $('html, body').animate({scrollTop:scrollto}, 0);
    
    0 讨论(0)
  • 2020-11-22 00:59

    Just discovered another pure CSS solution that worked like a charme for me!

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

    Found on this site!

    0 讨论(0)
提交回复
热议问题