【问题标题】:Toggle menu between two div container在两个 div 容器之间切换菜单
【发布时间】:2017-05-14 04:22:51
【问题描述】:

我可能遇到了一个相当简单的问题,但我自己无法解决。

我打算有 3 个 div,左右 div 应该作为守门人。中间的应该隐藏起来,直到我将鼠标悬停在门卫上。但是我希望中间 div 占用其他 div 留下的剩余空间。过渡也应该很顺利,但我可以自己管理。

到目前为止,这是我的代码:

<html>
<head>
<style>
    .navi{
        display: inline-block;
    }
    #middle{
        transition: width 1s ease-out;
        width: 0px;
        overflow: hidden;
        height: 0px;
    }
    nav{
        width: 100%;
        height: 169px;
        position: relative;
    }
    nav #left:hover + #middle{
        opacity: 1;
        height: auto;
        width: auto;
    }

    </style>
</head>
<body>
    <nav>
    <div id="left" class="navi"><img src="Left.png"></div>
    <div id="middle" class="navi">Lorem Ipsum</div>
    <div id="right" class="navi"><img src="Right.png"></div> 
    </nav>
</body>
</html>

这样做的问题是,它既不会占用所有剩余的空间,而且过渡看起来也不好看,因为文本出现在过渡的第一秒,然后就开始适应了,只要空间可用。

希望你能帮助我。

【问题讨论】:

  • 当你向左悬停时,你希望在右侧居中,当你悬停在右侧时,你希望在左侧居中。你希望这种变化顺利进行。但是当你悬停在中间时会发生什么?

标签: html css transition


【解决方案1】:

产生非常干净的结果的一种解决方案是通过包含滑动图像的父元素触发动画。这使得实现您想要的效果变得相当简单:

JSFiddle

希望对你有所帮助!

nav {
  position: relative;
  width: 100%;
  display: flex;
  justify-content: center;
}

nav:hover > #navi-middle {
  transition: all .5s ease-out;
  width: 100%;
  opacity: 1;
}

#navi-middle {
  transition: all .5s ease-out;
  width: 0px;
  overflow: hidden;
  opacity: 0;
  height: 150px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}
<body>
    <nav>
    <div id="left" class="navi"><a href="http://placehold.it"><img src="http://placehold.it/150x150"></a></div>
    <div id="navi-middle"><pre>Lorem Ipsum</pre></div>
    <div id="right" class="navi"><a href="http://placehold.it"><img src="http://placehold.it/150x150"></a></div> 
    </nav>
</body>

【讨论】:

  • 这正是我想要的,漂亮,谢谢。也感谢其他这么快回答的人。
【解决方案2】:

要仅使用 CSS 执行此操作,侧边栏需要位于“中间”元素之前,以便您可以使用相邻的选择器来定位它们。您可以使用order 在视觉上重新排列它们。然后您可以在flex-growflex-basiswidth 上转换/触发更改。我在这里通过速记语法转换flex-grow

nav {
  display: flex;
}

.side {
  width: 100px;
  background: #eee;
}

#middle {
  transition: flex 1s ease-out, opacity 1s ease-out;
  overflow: hidden;
  flex: 0 0 0;
  opacity: 0;
}

#left {
  order: 1;
}

.side:hover ~ #middle, #middle:hover {
  opacity: 1;
  flex: 1 0 0;
}
<nav>
  <div id="left" class="navi side"><img src="Left.png"></div>
  <div id="right" class="navi side"><img src="Right.png"></div>
  <div id="middle" class="navi">Lorem Ipsum</div>
</nav>

nav {
  display: flex;
}

.side {
  width: 100px;
  background: #eee;
}

#middle {
  transition: flex 1s ease-out, opacity 1s ease-out;
  overflow: hidden;
  flex: 0 0 0;
  opacity: 0;
}

#left {
  order: 1;
}

.side:hover ~ #middle, #middle:hover {
  opacity: 1;
  flex: 1 0 0;
}
<nav>
  <div id="left" class="navi side"><img src="Left.png"></div>
  <div id="right" class="navi side"><img src="Right.png"></div>
  <div id="middle" class="navi">Lorem Ipsum</div>
</nav>

【讨论】:

  • ...或将控制器/映射器用于一种情况或另一种情况。起初我也认为这是不可能的,然后意识到我只是处理错了。但是,提出的问题和选择的答案之间存在巨大差异,imo :)。
  • @AndreiGheorghiu 啊,是的,绝对令人困惑。选择的答案是一个整洁的效果,但也不是我的想法。当您将元素描述为“门卫”时,我想它可以在没有示例或绘图或其他东西的情况下进行猜测和解释。
【解决方案3】:

所以,我认为你可以这样做。

https://jsfiddle.net/pablodarde/gr6zzu8n/

HTML

<nav>
  <div id="left" class="navi"><img src="http://ii.designtoscano.com/fcgi-bin/iipsrv.fcgi?FIF=/images/toscano/source/SH4210_2.tif&wid=2048&cvt=jpeg" width="200px"></div>
  <div id="middle" class="navi">
    <div>
      Lorem Ipsum  
    </div>
  </div>
  <div id="right" class="navi"><img src="http://ii.designtoscano.com/fcgi-bin/iipsrv.fcgi?FIF=/images/toscano/source/SH4210_2.tif&wid=2048&cvt=jpeg" width="200px"></div> 
</nav>

CSS

.navi{
  display: inline-block;
}
#middle{
  transition: all 1s ease-out;
  width: 200px;
  text-align: center;
  max-width: 0px;
  overflow: hidden;
  max-height: 0px;
  opacity: 0;
}

nav{
  width: 100%;
  height: 169px;
  position: relative;
}
nav #left:hover + #middle{
  opacity: 1;
  max-height: 500px;
  max-width: 500px;
}

【讨论】:

    【解决方案4】:

    我假设您正在寻找这样的东西:

    body { margin: 0;}
    left {background-color: #600}
    right {background-color: #036}
    container {
      display:flex;
      position: relative;
      min-height: 100vh;
    }
    container * {
      flex: 1;
      transition: flex-grow .4s cubic-bezier(.4,0,.2,1);
      display: flex;
      justify-content: center;
      align-items: center;
      color: white;
      overflow: hidden;
      font-size: 3rem;
    }
    middle { 
      flex: 0;
      color: black;
    }
    container:hover middle {flex:1}
    one,two {
      position: absolute;
      height: 100%;
      width: 50%;
      left: 0;
    }
    two { left: 50%;}
    one:hover ~ right {flex: 0}
    two:hover ~ left {flex: 0}
    <container>
      <one></one>
      <two></two>
      <left>left</left>
      <middle>middle</middle>
      <right>right</right>
    </container>

    关键是不要将移动元素用作控制器,而是在每一半上放置两个“控制器”元素absolutely,指示后面的元素(保存内容)应该如何移动和排列。

    【讨论】: