"position:fixed在Chrome和IE中与离屏菜单不兼容"

43

意图

我正在使用CSS和JavaScript使用一个侧边栏转换菜单。 侧边栏菜单按预期工作。 我想要一个在屏幕左侧并在触发菜单时移动的侧边栏菜单。想法是拥有一个100像素宽、高度为100%且始终在屏幕左侧的菜单触发器。 使用绝对位置会导致在所有浏览器中出现高度问题,使用固定位置在Firefox上运行正常,但遇到下面提到的问题。

错误

Firefox问题:就我所知,没有任何问题。

Chrome问题:向下滚动几个像素后,侧边栏菜单触发器不会延伸到整个页面。

Internet Explorer:侧边栏似乎完全消失,当侧边栏菜单被触发时。

jsFiddle

因为我的代码涉及HTML、CSS和JavaScript,所以我包含了一个jsFiddle。请注意,据我所知,问题仅出现在Chrome和Internet Explorer上。您可以通过向下滚动页面一点并单击左侧菜单按钮来复制问题。

截图

侧边栏转换菜单问题

值得注意的HTML代码(完整代码在Fiddle中)

<div id="sbContainer" class="sbContainer">
    <div class="sbPush">
        <header class="contain-to-grid sbMenu sbFX">
            <nav class="top-bar" data-topbar>
                <ul class="title-area show-for-small-only"><!--SITENAME--></ul>
                <section class="top-bar-section"><!--LINKS--></section>
            </nav>
        </header>
        <div class="sbContent-one">
            <div class="sbContent-two">
                <div class="sbMenuTrigger" data-effect="sbFX"><!--SIDEBAR TRIGGER--></div>
                <div class="sbMainContent" role="document"><!--PAGE CONTENT--></div>
            </div>
        </div>
    </div>
</div>

值得注意的CSS代码(完整代码在Fiddle中)

html, body, .sbContainer, .sbPush, .sbContent-one {
    height:100%
}
.sbContent-one {
    overflow-x:hidden;
    background:#fff;
    position:relative
}
.sbContainer {
    position:relative;
    overflow:hidden
}
.sbPush {
    position:relative;
    left:0;
    z-index:99;
    height:100%;
    -webkit-transition:-webkit-transform .5s;
    transition:transform .5s
}
.sbPush::after {
    position:absolute;
    top:0;
    right:0;
    width:0;
    height:0;
    background:rgba(0,0,0,0.2);
    content:'';
    opacity:0;
    -webkit-transition:opacity 0.5s,width .1s 0.5s,height .1s .5s;
    transition:opacity 0.5s,width .1s 0.5s,height .1s .5s
}
.sbMenu-open .sbPush::after {
    width:100%;
    height:100%;
    opacity:1;
    -webkit-transition:opacity .5s;
    transition:opacity .5s
}
.sbMenu {
    position:absolute;
    top:0;
    left:0;
    z-index:100;
    visibility:hidden;
    width:244px;
    height:100%;
    background:#872734;
    -webkit-transition:all .5s;
    transition:all .5s
}
.sbMenu::after {
    position:absolute;
    top:0;
    right:0;
    width:100%;
    height:100%;
    background:rgba(0,0,0,0.2);
    content:'';
    opacity:1;
    -webkit-transition:opacity .5s;
    transition:opacity .5s
}
.sbMenu-open .sbMenu::after {
    width:0;
    height:0;
    opacity:0;
    -webkit-transition:opacity 0.5s,width .1s 0.5s,height .1s .5s;
    transition:opacity 0.5s,width .1s 0.5s,height .1s .5s
}
.sbFX.sbMenu-open .sbPush {
    -webkit-transform:translate3d(300px,0,0);
    transform:translate3d(244px,0,0)
}
.sbFX.sbMenu {
    -webkit-transform:translate3d(-100%,0,0);
    transform:translate3d(-100%,0,0)
}
.sbFX.sbMenu-open .sbFX.sbMenu {
    visibility:visible;
    -webkit-transition:-webkit-transform .5s;
    transition:transform .5s
}
.sbFX.sbMenu::after {
    display:none
}
.no-csstransforms3d .sbPush,.no-js .sbPush {
    padding-left:244px
}
.sbMenuTrigger {
    background-color:#b23445;
    cursor:pointer;
    height:100%;
    width:100px;
    position:fixed;
    left:0;
    top:0
}
.sbMainContent {
    margin-left:100px;
    width:calc(100% - 100px);
    top:0;
    padding-top:50px;
    position:absolute;
    height:100%
}

截图和fiddle不匹配...不确定fiddle正在演示什么。 - Populus
截图是从开发网站中获取的。如果您在Chrome或Internet Explorer中加载fiddle,则可以复制屏幕截图中显示的相同问题。 - Simon Hayter
1
Chrome 对我来说很好,但是我使用的是 Linux,因此可能会产生不同的结果。 - Populus
1
你滚动了页面再展开菜单吗? - Simon Hayter
3个回答

26
这里有一个解决方法,只需要进行很少的更改。
它在最新版本的FF、Chrome和IE11/10中都能够稳定运行。 更新示例
.sbContent-one {
  overflow: visible;       /* Or remove overflow-x: hidden */
}
.sbMainContent {
  overflow-x: hidden;
}
.sbMenuTrigger {
  position: static;        /* Or remove position: fixed */
}

在Chrome中解决问题的最简单方法是将.sbContent-oneoverflow移动到.sbMainContent。这样做可以防止你实际上滚动过.sbMenuTrigger元素(解决了问题),因为.sbMainContent是一个兄弟元素。
目前在浏览器中,关于fixed元素如何与使用translate3d变换的元素定位存在许多不一致之处。IE中的问题是由于fixed元素相对于窗口定位,而不考虑使用translate3d变换的元素。为了解决这个问题,完全避免固定定位,并通过删除position: fixed(或使用position: static,即默认值)将元素.sbMenuTrigger重新添加到正常流中。这样做,侧边栏就可以按预期扩展。换句话说:相对于元素定位的fixed元素与使用translate3d变换的元素之间存在很多不一致之处。
  • .sbContent-one 中删除 overflow-x: hidden(或使用 overflow: visible 覆盖它)。
  • overflow-x: hidden 添加到 .sbMainContent 中。
  • .sbMenuTrigger 中删除 position: fixed(或使用 position: static 覆盖它)。

1
感谢大家提供的解决方案。我已经授予Josh奖励,因为我相信这个解决方案符合我的要求,并解释了为什么其他方案不可行。其他人也加1分!谢谢! - Simon Hayter
1
@bybe 谢谢。我刚刚开始了另一个赏金,将授予Joe,因为他的解决方案同样有效。 - Josh Crozier
嗨,我刚在Safari 6和7上进行了测试,似乎菜单从某处获取margin:56px...使用.sbContainer margin-left 56px可以解决菜单打开时的问题,但关闭时会出现问题。唉!为什么浏览器不能都一样呢:P - Simon Hayter

10

以下是我的解决方案。在三个主流浏览器上测试过,可以正常工作!

查看示例

请注意以下类的更改:

  • .sbContent-one中移除position relative属性
  • .sbContent-two添加height: 100%属性(新规则)
  • .sbMainContent有重大更改
  • .sbMenuTrigger的position属性变更为absolute

主要问题如下:

  1. .sbContent-one.sbMainContent不必要地使用了position relative和absolute属性。
  2. position fixed属性相对于窗口位置固定,所以在元素转换时会因浏览器而异。

不确定为什么有人踩了这个..我点个赞1+..它基本上是有效的,尽管现在有一个小问题,因为您已经删除了position: relative..如果您比较您的全屏示例OP的全屏示例,您会发现文本“向下滚动并展开菜单以查看问题”现在偏移了..我很确定OP想要保持相对定位。 - Josh Crozier
@JoshCrozier 这是因为 JS Fiddle 的头部和 iframe。如果您设法打开干净的版本,您会看到它完美地工作。此外,我建议清除一些我认为不必要的样式,这就是为什么我包括了更多的更改。 - Jose Ch.

2
我已经在最新版本的Chrome/IE11上使其工作。
我将

移到了jsfiddle
        <div class="sbMenuTrigger" data-effect="sbFX">
            <div class="sbMenuIcon">
                <div class="sbMenuIconBackground"></div>
                <div class="sbMenuIconOverlay"></div>
            </div>
            <div class="sbMenuLogo">
                <div class="sbMenuLogoBackground"></div>
                <div class="sbMenuLogoOverlay"></div>
            </div>
        </div>

<header>标签的末尾,因此CSS变成了:
.sbMenuTrigger {
    background-color:#b23445;
    cursor:pointer;
    width:100px;
    position:absolute;
    right:-100px;
    top:0;
    bottom: 0;
}

位置固定+变换并不总是受到所有浏览器的欢迎。

1
解决了问题,但不喜欢使用负边距或位置的想法。此外,不确定你做了什么,但是在你的Fiddle上菜单无法关闭。 - Simon Hayter
当所有内容的宽度固定时,负边距并不是问题,对于无法关闭的失败,可能是由于移动HTML的原因造成的问题。 - romuleald

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