【问题标题】:Bootstrap: anchors and body top margin/paddingBootstrap:锚点和主体上边距/填充
【发布时间】:2013-01-09 16:25:11
【问题描述】:

我正在使用 Bootstrap,其全局导航栏固定在页面正文的顶部。

    <div class="navbar navbar-fixed-top navbar-inverse">
        <div class="navbar-inner">
            <div class="container">
                <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </a>
                <a class="brand" href="/">MyBrand</a>
                <div class="nav-collapse collapse">
                    <ul class="nav">
                        <li><a href="#>Page 1</li>
                        <li><a href="#>Page 2</li>
                        <li><a href="#>Page 3</li>
                    </ul>
                </div>
            </div>
        </div>
    </div>

我在正文顶部添加了一个 40 像素的边距,以便导航栏不会覆盖页面内容的顶部。

body {
    background-color: #f5f5f5;
    position: relative;
    margin-top: 40px;
}

到那里为止,一切正常。我还使用内部锚点来简化页面内的导航,使用 Twitter 与 Bootstrap 文档中的 affix 组件使用的相同机制,使用户能够跳转到页面内的不同部分(参见 http://twitter.github.com/bootstrap/getting-started.html

<a href="#section1">Section 1</a>
<a href="#section2">Section 2</a>
<a href="#section3">Section 3</a>

[...]

<section id="section1">
    [...]
    [...]
    [...]
</section
<section id="section2">
    [...]
    [...]
    [...]
</section
<section id="section3">
    [...]
    [...]
    [...]
</section>

我的问题是当用户点击时,浏览器将目标粘贴到屏幕的最顶部,内容消失在导航栏下。我注意到 Twitter 使用了一个技巧,目标 &lt;section&gt; 标签包括“padding-top: 30px;”,最接近的&lt;h1&gt; 包括“margin-top: 10px;” CSS 指令,以便将文本显示在屏幕顶部下方 40 像素处。

我不能让我在每个部分之间“丢失”40px,我的显示必须保持紧凑。我的问题是:有没有办法让内部锚不粘在屏幕视图的最顶部,而是远离屏幕顶部任意长度?

【问题讨论】:

    标签: twitter-bootstrap anchor margin navbar


    【解决方案1】:

    最后,我想出了如何轻松解决这个问题:

    body {
        background-color: #f5f5f5;
        position: relative;
        margin-top: 40px;
    }
    
    section {
        padding-top:40px;
        margin-top:-40px;
    }
    

    这意味着在正文顶部添加了 40px 的边距,在部分顶部添加了 40px 的内边距,还添加了负的 40px 边距,以便向上移动它们各自的预期位置,引入不可见的边距单击锚点后浏览器将显示绘制到某个部分时的帐户。

    希望对您有所帮助。

    【讨论】:

    • 这里的问题完全相同。我会给你的解决方案一个机会,但我担心它会搞砸其他事情。啊,CSS...
    • 唉,它在视觉上可以正常工作,但是 40px 中的任何可点击部分(或更多/更少,取决于您的顶栏)都无法点击。仍在寻找更好的解决方案...
    • @Cystack 那空间被导航栏占用了不是吗?不管怎样,看来你的问题可以用 z-index 解决,你试过了吗?
    • @MaxEvron 这对我也有用,我想你可以接受你的回答。
    • 如果您使用的是响应式,则必须为 @media (max-width: @navbarCollapseWidth) 恢复此不可见边距
    【解决方案2】:

    要让它滚动到正确的位置并在滚动页面时使所选菜单项正确,您需要在锚点上设置padding-top: 40px;,并在锚点的前一个兄弟上设置margin-bottom: -40px;

    您可以使用 JS sn-p 来实现这一点,它会从导航菜单中找到元素并应用样式更改。

    $("header .nav a[href!=#]").each(function(){
        $($(this).attr("href")).css("padding-top", "40px").prev().css("margin-bottom", "-40px");
    });
    

    【讨论】:

    • 我认为 $("header .nav a[href^=#]") 非常适合避免其他链接。
    【解决方案3】:

    如果您的应用程序可以应用 javascript,那么以下 javascript 也可以正常工作:

    function maybeScrollToHash() {
        if (window.location.hash && $(window.location.hash).length) {
            var newTop = $(window.location.hash).offset().top - $('.navbar-fixed-top').height() + parseInt($('body').css('padding-top'),10);
            $(window).scrollTop(newTop);
        }
    }
    
    $(window).bind('hashchange', function() {
    maybeScrollToHash();
    });
    
    maybeScrollToHash(); 
    

    对此处找到的答案稍作修改:https://github.com/twbs/bootstrap/issues/193

    唯一的区别是上面的代码适用于 navbar-fixed-top 类。

    【讨论】: