将元素定位在父元素的右上角并确保环绕它

aza*_*gru 5 css flexbox

我想为任意数量的元素创建一个容器,并带有展开/折叠按钮。按钮应位于容器的右上角,并且容器内的元素应环绕按钮。这是这个想法:

\n\n

在此输入图像描述

\n\n

我制作了这个元素的快速Codepen 原型,但我能想出的将按钮定位在右上角的唯一方法是float: right

\n\n

html:

\n\n
<div class="container closed">\n  <button>Click</button>\n  <!-- some divs with class "child" inserted with js -->\n</div>\n
Run Code Online (Sandbox Code Playgroud)\n\n

CSS:

\n\n
.container {\n  height: 80px;\n  width: 330px;\n  margin: auto;\n}\n\nbutton {\n  float: right;\n  margin: 1.3em 1.6em 0 0;\n}\n\n.closed {\n  overflow-y: hidden;\n}\n\n.child {\n  width: 50px;\n  height: 30px;\n  background-color: grey;\n  display: inline-block;\n  margin: 1em;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以这似乎可以工作float: right,但浮动是如此通过\xc3\xa9 :-) 有没有更干净的方法来定位按钮?我认为 Flexbox 能够做到这一点,但无法找到使用 Flexbox 实现此目的的方法。有什么建议吗?

\n\n

UPD:添加了相关的 html 和 css 代码。

\n

Roy*_*Roy 5

如果你使用CSS3的flexbox属性,你可以纯粹用CSS来实现这一点flex,就像你说的那样。我做了一个小演示来证明这一点。

CSS的核心部分在这里:

display: flex;
flex-flow: row-reverse wrap;
Run Code Online (Sandbox Code Playgroud)

display: flex在可用宽度上拉伸内容,并将row-reverse从右到左对齐项目(默认情况下 LTR )。在 MDN 上了解有关 Flexbox 的更多信息。

另一部分是菜单高度的切换,我不知道你可以有多少个项目,但在演示中我使用了一些普通的 JavaScript 来展开和折叠菜单。

var mainNav = document.getElementById('menu-list');
var navToggle = document.getElementById('expandbutton');

function mainNavToggle() {
  mainNav.classList.toggle('expanded');
}

navToggle.addEventListener('click', mainNavToggle);
Run Code Online (Sandbox Code Playgroud)
.menu {
  height: 60px;
}

.list,
.list-item {
  list-style: none;
  margin: 0;
  padding: 0;
}

.list {
  width: 100%;
  display: flex;
  flex-flow: row wrap;
  height: 50px;
  overflow: hidden;
}

.list-item {
  width: 25%;
  padding: 3px;
  box-sizing: border-box;
}

.btn {
  background-color: teal;
  display: block;
  padding: 10px;
  box-sizing: border-box;
  border-radius: 3px;
  margin: 5px 0;
  color: white;
  text-decoration: none;
}

.top-right {
  border: 0;
  width: 100%;
  display: block;
  background-color: red;
}

.list.expanded {
  height: 100px;
}

.list > .list-item:nth-last-child(n+4) ~ .list-button {
  order: 1;
}

.list > .list-item:nth-child(n+4) {
  order: 2;
}
Run Code Online (Sandbox Code Playgroud)
<div class="menu">
  <ul class="list" id="menu-list">
    <li class="list-item"><a href="#" class="btn">Button</a></li>
    <li class="list-item"><a href="#" class="btn">Button</a></li>
    <li class="list-item"><a href="#" class="btn">Button</a></li>
    <li class="list-item"><a href="#" class="btn">Button</a></li>
    <li class="list-item"><a href="#" class="btn">Button</a></li>
    <li class="list-item"><a href="#" class="btn">Button</a></li>
    <li class="list-item list-button">
      <button href="#" id="expandbutton" class="btn top-right">Expand</button>
    </li>
  </ul>
</div>
Run Code Online (Sandbox Code Playgroud)

编辑

我更新了代码片段,flexbox其属性order在这种情况下确实有帮助(MDN 参考)。

.list > .list-item:nth-last-child(n+4) ~ .list-button {
  order: 1;
}

.list > .list-item:nth-child(n+4) {
  order: 2;
} 
Run Code Online (Sandbox Code Playgroud)

order的初始值为0。如果你想移动订单,它必须高于初始值,所以这就是为什么我们需要设置.list-buttonto的项目order: 1按钮后面的所有元素都需要位于按钮后面或按钮下方(每行 4 个元素的情况下),因此:nth-child(n+4)需要一个order: 2. 请参阅更新的小演示片段。