响应式弹性行显示,直到达到最小宽度

Responsive flex row display until min width reach

基本上,在一个容器中,我有选项卡(ul.li)和这些选项卡旁边的另一个 div(搜索框),这些选项卡使用 flex 显示在一行中。

我希望它按照以下工作流程响应:

我复制了最简单的例子来说明我在说什么。

body {
  padding: 50px;
  font-family: sans-serif;
}

.container {
  resize: horizontal;
  overflow: auto;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  border: 1px solid black;
}

.tabs__list {
  align-items: flex-start;
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  border-bottom: 0;
  margin-right: 28px;
  width: unset;
}

button {
  height: 34px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search {
  flex-basis: 100%;
  height: 34px;
  align-self: end;
  min-width: 100px;
  background-color: blue;
}
<div class="container">
  <ul class="tabs__list">
    <li>
      <button type="button">Tab Item Number One</button>
    </li>
    <li>
      <button type="button">Tab Item Number Two</button>
    </li>
  </ul>
  <div class="search"></div>
</div>

要使元素 ellipsis 正常工作,最重要的是宽度。如果没有宽度,浏览器将不知道何时实际从其预定义的宽度中剪切文本。我将容器的宽度设置为 100%。然后将每个子元素(tabs__listsearch)设置为 50%。我还将 li 设置为 50%,因此每个项目将占据 space 的一半。但是,我还有 flex-basis: 100%;,所以 search 会填充剩余的 space。

有了这个设置,您现在只需将 width: 100%; 设置为您的 button,这是它需要的定义宽度,因此它知道文本被截断并且需要显示省略号。

旁注:你仍然可以将你的min-width: 100px;添加到search,它仍然会显示省略号,但我删除了它,因为它显示了一个垂直滚动条。

body {
  padding: 50px;
  font-family: sans-serif;
}

.container {
  resize: horizontal;
  overflow: auto;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  border: 1px solid black;
  width: 100%;
}

.tabs__list {
  align-items: flex-start;
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  border-bottom: 0;
  margin-right: 28px;
  width: 25%;
}

li {
  width: 50%;
}

button {
  height: 34px;
  width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search {
  flex-grow: 1;
  flex-basis: 100%;
  width: 75%;
  min-width: 100px;
  height: 34px;
  align-self: end;
  background-color: blue;
}
<div class="container">
  <ul class="tabs__list">
    <li>
      <button type="button">Tab Item Number One</button>
    </li>
    <li>
      <button type="button">Tab Item Number Two</button>
    </li>
  </ul>
  <div class="search"></div>
</div>

您需要在 flex 容器的子项上利用 flex-growflex-shrinkflex-basis 属性的强大功能。

This 是来自 Kevin Powell 的非常方便的 YouTube 教程,解释了这些属性和其他重要的 flex-box 概念。

无论如何,这里是您的问题的解决方案,其中的注释解释了添加的内容和原因。

body {
  padding: 50px;
  font-family: sans-serif;
}

.container {
  resize: horizontal;
  display: flex;
  overflow: auto;
  align-items: center;
  flex-wrap: nowrap;
  /* don't allow items to go to a new line on shrink */
  border: 1px solid black;
  min-width: 138px;
  /* 100px for the div.search width + 10px inline padding for div.search + 28px margin-rigt from ul.tabs__list */
}

.tabs__list {
  flex-grow: 0;
  /* this forbids ul from growing, so only div.search can take the remaining space */
  flex-shrink: 1;
  /* this allows ul to shrink */
  flex-basis: content;
  list-style: none;
  margin: 0;
  padding: 0;
  border-bottom: 0;
  margin-right: 28px;
  overflow: hidden;
  /* styling the ul with nowrap so that the li's do not go on the next line on shrink */
  display: flex;
  flex-wrap: nowrap;
}

.search {
  flex-grow: 1;
  /* this allows div.search to grow and take up the remaining space */
  flex-shrink: 0;
  /* this forbids div.search to shrink below 100px */
  flex-basis: 100px;
  /* this works quite like min-width: 100px; but not exactly the same */
  align-self: end;
  height: 45px;
  background-color: blue;
  /* more suggested styling to div.search */
  color: white;
  display: flex;
  align-items: center;
  padding: 5px;
}

.tabs__list li {
  /* display: inline; */
  margin: 5px;
  padding: 5px;
  flex: auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* the following styling is applied to give li's the look of a button */
  border: black 1px solid;
  text-align: center;
  background-color: lightgray;
  cursor: pointer;
}

.tabs__list li:hover {
  background-color: gray;
  color: white;
}
<div class="container">
  <ul class="tabs__list">
    <li> Tab Item Number One</li>
    <li>Tab Item Number Two</li>
  </ul>
  <div class="search">Search</div>
</div>