앵커가 작동하는 방식을 정리하려고 합니다. 페이지 상단에 고정된 헤더가 있으므로 페이지의 다른 곳에서 앵커에 링크하면 앵커가 페이지 상단에 있도록 페이지가 점프하여 고정된 헤더 뒤에 콘텐츠가 남습니다. 그것은 의미가 있습니다). 헤더 높이에서 25px만큼 앵커를 오프셋하는 방법이 필요합니다. HTML이나 CSS를 선호하지만 Javascript도 허용됩니다.
질문자 :Matt Dryden
자바스크립트 없이 CSS만 사용할 수 있습니다.
앵커에게 다음과 같은 수업을 제공하세요.
<a class="anchor" id="top"></a>
그런 다음 앵커를 블록 요소로 만들고 상대적으로 배치하여 페이지에 실제로 나타나는 위치보다 높거나 낮은 오프셋을 앵커에 배치할 수 있습니다. -250px는 앵커를 250px 위로 배치합니다.
a.anchor { display: block; position: relative; top: -250px; visibility: hidden; }
Jan
이 솔루션을 찾았습니다.
<a name="myanchor"> <h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1> </a>
이렇게 하면 콘텐츠에 간격이 생기지 않으며 앵커 링크가 정말 잘 작동합니다.
Alexander Savin
이에 대한 해결책도 찾고 있었습니다. 제 경우에는 꽤 쉬웠습니다.
모든 링크가 포함된 목록 메뉴가 있습니다.
<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를 가진 내 태그 안에 span 태그를 넣습니다.
<h3><span id="one"></span>one</h3>
이제 CSS 2줄을 사용하여 적절하게 배치합니다.
h3{ position:relative; } h3 span{ position:absolute; top:-200px;}
고정 헤더(또는 그 이상)의 높이와 일치하도록 상단 값을 변경합니다. 이제 이것이 다른 요소와도 작동한다고 가정합니다.
Hrvoje Miljak
이것이 프레젠테이션의 문제이므로 순수한 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);
Ian Clark
FWIW 이것은 나를 위해 일했습니다.
[id]::before { content: ''; display: block; height: 75px; margin-top: -75px; visibility: hidden; }
Mark Nottingham
Alexander Savin에서 영감을 받은 순수 CSS 솔루션:
a[name] { padding-top: 40px; margin-top: -40px; display: inline-block; /* required for webkit browsers */ }
선택적으로 대상이 여전히 화면 밖에 있는 경우 다음을 추가할 수 있습니다.
vertical-align: top;
Ziav
내 솔루션은 CMS의 대상 선택자와 이전 선택자를 결합합니다. 다른 기술은 앵커의 텍스트를 고려하지 않습니다. 높이와 음수 여백을 필요한 오프셋으로 조정하십시오...
:target::before { content: ''; display: block; height: 180px; margin-top: -180px; }
Lezz
이것은 이전 답변에서 많은 요소를 가져와 작은(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);
못생긴 버전:
!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);
Lance
js 없이 html을 변경하지 않고도 할 수 있습니다. CSS 전용입니다.
a[id]::before { content: ''; display: block; height: 50px; margin: -30px 0 0; }
그러면 id가 있는 모든 a-태그 앞에 의사 요소가 추가됩니다. 헤더의 높이와 일치하도록 값을 조정합니다.
Zsolt Szilagyi
최신 브라우저의 경우 CSS3 :target 선택기를 페이지에 추가하기만 하면 됩니다. 이것은 모든 앵커에 자동으로 적용됩니다.
:target { display: block; position: relative; top: -100px; visibility: hidden; }
Alessandro Alinone
나는 비슷한 문제에 직면했지만 불행히도 위의 모든 솔루션을 구현한 후 다음과 같은 결론에 도달했습니다.
- 내 내부 요소는 깨지기 쉬운 CSS 구조를 가지고 있었고 상대적/절대적인 위치를 구현하는 것은 페이지 디자인을 완전히 깨뜨리는 것이었습니다.
- CSS는 제 강점이 아닙니다.
헤더로 인한 오프셋을 설명하고 div를 약 125픽셀 아래로 재배치하는 이 간단한 스크롤 js를 작성했습니다. 적합하다고 생각되는 대로 사용하십시오.
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; } } });
여기에서 라이브 구현을 참조하십시오.
Shouvik
@moeffju가 제안하는 것처럼 이것은 CSS를 사용 하여 달성할 수 있습니다. 내가 만난 문제(논의하지 않은 것에 놀랐음)는 패딩 또는 투명한 테두리로 이전 요소를 겹치는 트릭으로 해당 섹션의 맨 아래에 있는 호버 및 클릭 동작을 방지합니다. z 순서.
내가 찾은 가장 좋은 수정 z-index: 1
div
섹션 콘텐츠를 배치하는 것입니다.
// 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; }
Kris Braun
위치 속성을 변경하는 솔루션이 항상 가능한 것은 아니므로(레이아웃을 파괴할 수 있음) 다음과 같이 제안합니다.
HTML:
<a id="top">Anchor</a>
CSS:
#top { margin-top: -250px; padding-top: 250px; }
이것을 사용하십시오:
<a id="top"> </a>
겹침을 최소화하고 font-size를 1px로 설정합니다. 일부 브라우저에서는 빈 앵커가 작동하지 않습니다.
user2475125
같은 문제에 대해 쉬운 솔루션을 사용했습니다. 각 앵커에 40px의 패딩 상단을 배치합니다.
odupont
이 링크에 제공된 답변에서 일부 코드를 차용하면(저자가 지정되지 않음) 앵커에 좋은 부드러운 스크롤 효과를 포함할 수 있으며 앵커 위의 -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(){ }); });
Mark C Mitchell
앵커가 테이블 요소이거나 테이블(행 또는 셀) 내에 있는 경우 위의 방법은 잘 작동하지 않습니다.
이 문제를 해결하려면 javascript를 사용하고 window hashchange
이벤트에 바인딩해야 했습니다( demo ).
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 이벤트를 사용할 수 있는 것은 아닙니다.
Mottie
페이지 콘텐츠의 나머지 부분에 의해 겹쳐지는 고정 위치 탐색 모음을 사용하는 대신(전체 페이지 본문이 스크롤 가능함), 대신 정적 탐색 모음이 있는 스크롤할 수 없는 본문을 가진 다음 페이지 콘텐츠를 아래 절대 위치 스크롤 가능 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에 첨부된다는 것입니다. 이것이 바람직하다고 생각할 수도 있고 그렇지 않을 수도 있습니다.
Mark Amery
a[name]:not([href])
CSS 선택기를 사용하여 ID 없이 이를 수행할 수 있습니다. 이것은 단순히 이름이 있고 href가 없는 링크(예: <a name="anc1"></a>
예제 규칙은 다음과 같습니다.
a[name]:not([href]){ display: block; position: relative; top: -100px; visibility: hidden; }
Chris GW Green
이것은 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(); });
Alice Wonder
모든 "콘텐츠 요소"가 다음과 같이 래핑된 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
사용할 수 없다는 것입니다.
lipsumar
Ziav의 대답에 추가 (알렉산더 아버님 께 구원 덕분에), 나는 구식 이용해야 <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; }
Prashant Tiwari
h1
요소 앞에 앵커를 고정하는 40px-height .vspace
<div class="vspace" id="gherkin"></div> <div class="page-header"> <h1>Gherkin</h1> </div>
CSS에서:
.vspace { height: 40px;}
잘 작동하고 공간이 답답하지 않습니다.
Quentin
탐색 모음의 높이를 제공하는 연결 가능한 ID가 있는 숨겨진 스팬 태그는 어떻습니까?
#head1 { padding-top: 60px; height: 0px; visibility: hidden; } <span class="head1">somecontent</span> <h5 id="headline1">This Headline is not obscured</h5>
Pete
다음 속성을 사용하여 앵커를 추가할 수도 있습니다.
(text-indent:-99999px;) visibility: hidden; position:absolute; top:-80px;
부모 컨테이너에 상대적인 위치를 지정합니다.
나를 위해 완벽하게 작동합니다.
Sanjo Elstak
@Jan의 훌륭한 답변에 대한 또 다른 변형은 이것을 jQuery(또는 MooTools)를 사용하는 #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 헤더를 좋아하는 사람에게 유용할 것입니다!
Dzseti
이 동일한 문제가 발생하여 다음과 같이 클릭 이벤트를 수동으로 처리하게 되었습니다.
$('#mynav a').click(() -> $('html, body').animate({ scrollTop: $($(this).attr('href')).offset().top - 40 }, 200 return false )
물론 스크롤 애니메이션은 선택 사항입니다.
jean
@AlexanderSavin의 솔루션은 WebKit
브라우저에서 잘 작동합니다.
FF
, Opera
및 IE9
에서 패딩을 조정하기 위해 선택한 앵커에 스타일을 적용 하는 :target 의사 클래스를 사용해야 했습니다.
a:target { padding-top: 40px }
이 스타일은 Chrome
/ Safari
용이 아니므로 CSS 핵, 조건부 주석 등을 사용해야 합니다.
inline
이라는 사실 때문에 Alexander의 솔루션이 작동한다는 사실을 알고 싶습니다. 링크를 원하지 않으면 display
속성을 간단히 변경할 수 있습니다.
<div id="myanchor" style="display: inline"> <h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1> </div>
jibiel
다음은 우리 사이트에서 사용하는 솔루션입니다. 헤더 높이가 무엇이든 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; });
stacigh
출처 : http:www.stackoverflow.com/questions/10732690/offsetting-an-html-anchor-to-adjust-for-fixed-header
'etc. > StackOverFlow' 카테고리의 다른 글
require, include, require_once 및 include_once의 차이점은 무엇입니까? (0) | 2023.04.15 |
---|---|
C에서 함수 포인터는 어떻게 작동합니까? (0) | 2023.04.15 |
jQuery로 확인란이 선택되어 있는지 확인하십시오. (0) | 2023.04.15 |
URL에 대한 Path.Combine? (0) | 2023.04.15 |
배열 배열 병합/평면화 (0) | 2023.04.15 |