一个宽度以百分比为单位设置的 `position:fixed` 侧边栏?

9

我成功地使用了优美的Susy网格系统创建了一个响应式布局,类似于WebDesignerWall.com

enter image description here

但是我无法实现一个position:fixed侧边栏。

这样的侧边栏在页面滚动时不会滚动而保持在同一位置。这非常方便(无论如何,您实际上不能将更多内容放入侧边栏,因为在窄窗口中它会使页面顶部混乱)。

当我对列应用position:fixed时,我的布局就会变得混乱: enter image description here 这些彩色块被声明为三列宽度,但是当对侧边栏应用position:fixed时它们会延伸得更远。

我认为问题是侧边栏的宽度是相对的,即以百分比设置。由于position:fixed,宽度是针对浏览器窗口而不是其容器进行测量的(尽管我将容器设置为position:relative)。

问题是:如何使一个列固定在窗口上,同时将其宽度测量针对其容器而不是视口

也许可以使用JS固定元素的位置?

PS:我尝试过width: inherit解决方法,但对我没有任何帮助。


我想将这个问题标记为有至少四个答案完全忽略了你的问题背景 - 即Susy - 而是提供了无关的解决方案,但问题本身很好; 我该怎么做?如果它们都停留在0,那么crud答案堆叠起来是否可以?(具有讽刺意味的是,一个答案说“只需使用数学!”-这正是Susy为您做的。) - iono
tomeoftom,为什么你要谴责这个问题呢?这个问题本身是完全有效的,并且符合StackOverflow的标准。这个问题有一个非常无可辩驳的答案(来自Susy的作者!),我很高兴将其标记为已接受。它是未来使用的绝佳参考。我只是不明白你的观点。 - Andrey Mikhaylov - lolmaus
1
不,这就是我想说的!这是一个非常棒的问题! - iono
编辑:并且已经有了完美的答案 - 我一直在想如何在不冒犯你的情况下删除那些不好或无关紧要的回答。我没有标记这个问题 - 我在思考如何最好地引起管理员的注意,而不是单独标记每一个不好的回答。 - iono
5个回答

11

做到这一点的方法是使用第二个容器。我不知道你的确切代码,但这里有一个例子。假设你的结构类似于这样:

<div class="page">
  <header class="banner">
    <h1>header</h1>
  </header>
  <nav class="navigation">
    <ul class="nav-inner">
      <li>navigation link</li>
    </ul>
  </nav>
  <article class="main">
    <h2>main content</h2>
  </article>
  <footer class="contentinfo">
    <p>footer</p>
  </footer>
</div>

我在那里唯一重要的假设是确保我的导航侧边栏有一个额外的包装器。我同时使用了<nav>标签和<ul>标签来工作。您可以使用任何标签,只要侧边栏有两个可用于结构的标签 - 外部用于固定容器,内部用于侧边栏本身。CSS如下:

// one container for everything in the standard document flow.
.page {
  @include container;
  @include susy-grid-background;
}

// a position-fixed container for the sidebar.
.navigation {
  @include container;
  @include susy-grid-background;
  position: fixed;
  left: 0;
  right: 0;
  // the sidebar itself only spans 3 columns.
  .nav-inner { @include span-columns(3); }
}

// the main content just needs to leave that space open.
.main { @include pre(3); }

// styles to help you see what is happening.
header, article, .nav-inner, footer {
  padding: 6em 0;
  outline: 1px solid red;
}

祝福。


1
感谢 @eric-meyer,您的解决方案非常完美!还有一个小细节:应该给固定块应用负的 z-index,这样它就不会重叠到主区域上,导致主区域无法点击。 - Andrey Mikhaylov - lolmaus
哦,是的。通常情况下,如果固定容器的唯一内容是浮动元素,那么该容器应该会折叠并且不会引起任何问题。但是如果它确实引起了问题,z-index 是一个很好的解决方法。 - Miriam Suzanne
嗨Eric,z-index的解决方案在Chrome中失效了。固定列出现在容器下面,在Chrome中无法点击。:( - Andrey Mikhaylov - lolmaus
1
是的,z-index只对定位元素起作用。请参见:http://coding.smashingmagazine.com/2009/09/15/the-z-index-css-property-a-comprehensive-look/ - Miriam Suzanne
2
.navigation的高度设置为0对我很有效,并且无需设置任何z-index。 - iono
显示剩余2条评论

1
也许可以用JS来固定元素的位置吗?
是的,但这将会很繁琐,而且不是理想的解决方案。
相反,使用JavaScript计算适当的宽度并分配它,而不是直接在CSS中使用百分比。以下是一个基本的概述:
function updateSize() {
    var outer = document.getElementById("outercontainer"); //get the container that contains your sidebar
    var navcol = document.getElementById("navcol"); //get the sidebar (which is supposed to have position: fixed;)
    navcol.style.width = Math.floor(outer.offsetWidth * 45/100) + "px"; //or whatever your percentage is
}
updateSize();
window.onresize = updateSize; /*make sure to update width when the window is resized*/

注意: 上述使用的ID仅为占位符--您需要修改它们以适应您的实际页面。


1

您无法这样做,固定位置元素与其容器分离,需要使用position: relative或没有position: relative。只需将其宽度设置为绝对值-看起来您的内容始终为760像素宽,是吗?


这是第三个忽略问题背景——Susy网格系统的答案。 - iono
@tomeoftom:这不是在说JavaScript不能回答jQuery的问题吗? :| - Ry-
完全不是这样。Sass在CSS中实现了物理上不可能的事情。Susy所提供的网格布局类型意味着您必须为屏幕上的每个元素重新计算和重新输入单独的宽度百分比,以适应每个布局更改。很遗憾,我们目前无法依赖flexbox,但在此之前,Susy是我们正确抽象样式与标记的最佳方式之一。相反,jQuery是一个使用Javascript构建的库 - 您始终可以重新创建其组件。 - iono
@tomeoftom:我不是很喜欢CSS预处理器,但它只是一个CSS预处理器,而不是魔法浏览器支持的样式系统。所以并非真正的物理不可能。无论如何,这仍然是正确的——使用Sass mixin或不使用都可以将其宽度设置为绝对值。 - Ry-
这个讨论有点毫无意义。CSS 不能进行自定义数学计算。这就是所谓的“魔法”。这也是为什么这个问题被放在Susy的背景下,因为作者,我想,不想每次调整网格比例时都要用计算器来计算确切的列和间距宽度。 - iono
@tomeoftom:好的,那么使用Sass mixin代替“760px”。我同意。这次讨论的重点是什么? - Ry-

-1

为什么不直接使用数学呢?=)

HTML示例:

 <div class="container">
    <div class="col">
        <div class="fixed">This is fixed</div>
    </div>
</div>

CSS

.container {
    width: 80%;
    margin: 0 auto;
}

.col {
   float: left;
    width: 33.3333333333%;
}

.fixed {
    position: fixed;
    width: 26.666666666%; /* .container width x .col width*/
}

-1

position:fixedposition:absolute 一样工作,因此它不是相对于其容器定位的。它只是浮动到您的文档中。 一个快速修复方法可能是这样的:

<div id="fixed-element" style="width:30%"> /* 30% of the document width*/
lorem ipsum dolor sit amet
</div>

<div id="faux-sidebar" style="width:30%; display:block"> /* 30% of the document, leave it empty, so it acts like a placeholder for the fixed element*/
&nbsp;
</div>

<div id="the-rest" style="width:70%"> /* the rest of the website goes here */
more lorem ipsum than ever before
</div>

我不确定这个答案是关于Susy的。 - iono

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接