css - 目视向下滑动固定元素,元素在 flex-end 对齐

标签 css flexbox css-transitions slide

我在我的移动网络应用程序中显示一个类似应用程序抽屉的组件,我在其中使用带有更多的底部导航图标,这会打开其他选项。

一些选项抽屉事实

  1. 向上/向下滑入/滑出 View
  2. 具有全屏高度
  3. 垂直对齐底部的元素
  4. 每行显示 N 个选项(不像附加图片每行只有一个选项)
  5. 放置在屏幕底部与主底部导航相同的 position: fixed 容器中。

我的选项抽屉应该像在这个 iOS 动画 GIF 上看到的那样动画

https://jsfiddle.net/LL4dst15/

App drawer

问题

我的抽屉正在使用 flexbox(正如您从示例中看到的那样),它将元素与横轴上的 flex-end 对齐,以将它们显示在最底部。但问题在于固定位置的导航容器,它具有这样的 z-index,它始终显示在内容上。

translateY 问题

如果我使用 translateY 抽屉实际上会按原样滑入/滑出,但抽屉元素的位置不会改变,这意味着导航容器仍然具有抽屉 + 底栏的高度。这可以在我左边的 fiddle 示例中看到,其中始终可以看到灰色元素。因此,这将覆盖我的实际内容,因此用户将难以与之交互。

但是我可以使用 pointer-events: none; 但我认为这是一个相当丑陋的 hack,可能有问题的浏览器支持。所以我想避免它。

最大高度问题

如果我使用 max-height 而不是转换,那么导航容器实际上会在抽屉调整大小时调整大小。这种方法的问题是抽屉似乎不会向上/向下滑动,而是像百叶窗一样折叠 ...原因是与柔性端的交叉轴对齐。如果我对齐到 flex start,那么它看起来就像是滑出。

我试图用自动边距解决这个问题,但似乎无法让它工作,所以我会使用 flex start 交叉轴对齐,但使用自动边距将内容推到抽屉底部。运气不好...

你有任何其他建议我应该如何做 CSS 才能让我的抽屉滑动并且我的容器也会调整大小?

最佳答案

我尝试使用 css 动画和关键帧; JS Fiddle

只剩下一个问题:当您加载页面时,代码也会运行。这可以通过一些 jQuery 轻松解决。

我所做的简短版本:我对 transform: translateY() 进行动画处理以获得您想要的效果,然后在动画的最后 % 中我将您的最大高度设置为:0vh。就我个人而言,我更愿意使用 jQuery 来执行此操作,但是您想要一个 css 解决方案,所以在这里。

这是代码(css 现在有点困惑,因为所有注释掉的东西,但清理它是你的工作):

html

Click any bottom bar item to toggle options drawer
<nav>
  <ul class="bottom-nav">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
    <li>Four</li>
  </ul>
  <ul class="extras" label="Uses 'translateY' to slide drawer">
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
  </ul>
</nav>
<nav>
  <ul class="bottom-nav">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
    <li>Four</li>
  </ul>
  <ul class="extras" label="Uses 'max-height' to slide drawer">
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
    <li>Option</li>
  </ul>
</nav>

CSS

html, body {
  background-color: #fff;
  line-height: 1.25rem;
  margin: 0;
}
nav {
  position: fixed;
  bottom: 20px;
  left: 10px;
  width: 300px;
  display: flex;
  flex-direction: column;
  background-color: #eee;
  border: 1px solid #fcc;

  ul {
    list-style: none;
    margin: 0;
    padding: 0;
    li {
      margin: 0;
      padding: 0;
    }
  }

  @mixin drawer() {
    width: 100%;
    display: flex;
    flex-flow: row wrap;
    align-content: flex-end;
    align-items: flex-start;
    cursor: default;
    background-color: #fff;
    box-shadow: 0 0 10px #999;
    overflow: hidden;
    &:before {
      content: attr(label);
      position: absolute;
      margin: 5px 0 0 10px;
      color: #999;
      font-size: 0.8125rem;
      font-style: italic;
    }
    li {
      flex-basis: 25%;
      text-align: center;
      padding: 1rem 0;
      &:hover {
        background-color: #f4f4f4;
      }
    }    
  }

  .bottom-nav {
    @include drawer();
    order: 1;
    z-index: 1;
  }

  .extras {
    @include drawer();
    order 0;
    z-index: 0;
    /* 100vh   = full height
     * 3.25rem = bottom nav bar (2×1rem padding + 1.25 line height)
     * 1.25rem = top text line height
     * 20px    = navigation fixed position bottom offset
     * 2px     = navigation container top and bottom border
     */
    height: calc(100vh - 3.25rem - 1.25rem - 20px - 2px);
    /*transform: translateY(100%);*/
    /*transition: transform 1s, opacity 0.5s;*/
    animation: closedrawer 10s forwards;
  }
  &.open {
    .extras {
      /*opacity: 1;*/
      animation: opendrawer 10s 1 forwards;
      /*transform: none;*/
      /*transition: transform 1s, opacity 0.5s 0.25s;*/
    }
  }

  + nav {
    left: 320px;

    .extras {
      /*transform: none;
      max-height: 0;
      transition: max-height 1s, opacity 0.5s 0.25s;*/
    }

    &.open {
      .extras {
        /*max-height: 100vh;
        transition: max-height 1s, opacity 1s;*/
      }
    }
  }
}
@keyframes opendrawer {
    0% {transform: translateY(100%); opacity: 1;}
    99% {background-color: blue; transform: translateY(0%); max-height: 100vh;}
    100% {background-color: blue; transform: translateY(0%);max-height: 100vh;opacity:1;}
}
@keyframes closedrawer {
  0%{transform: translateY(0%)}
   99% {background-color: red; transform: translateY(100%);max-height: 100vh; opacity: 1;}
    100% {background-color: red; transform: translateY(100%); max-height: 0vh; opacity: 0;}
}

javascript

$(function(){
    $(".bottom-nav li").click(function(evt){
    evt.preventDefault();
$(this).closest("nav").toggleClass("open");
  })
})

关于css - 目视向下滑动固定元素,元素在 flex-end 对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41503946/

相关文章:

javascript - 如何通过动画显示正在排序的 HTML 元素

javascript - 如何从 ajax 响应/在 JS 函数中加载 CSS/Javascript - 跨浏览器方式

html - 保持 flex 元素的纵横比

css - Flexbox 在 Safari 中仍然不稳定,flex-wrap 不起作用

css - 带有 svg 的响应式 flex 列

jquery - 重写 Jquery fadeIn() 以使用 CSS3 过渡

javascript - 使用 jQuery .addClass 函数

javascript - 与 CSS 属性名称的 jQuery.camelCase 相反

css - Safari 浏览器不支持伪元素的过渡?

java - 如何删除 JFX 中的舞台按钮