Home > Software engineering >  Responsive flex row display until min width reach
Responsive flex row display until min width reach

Time:03-24

Basically, in a container, I have tabs (with ul.li) and another div (search box) next to these tabs which are displayed in a row using flex.

Example

I want it responsive following this workflow:

  • if the width increases, the search section increases to fit the available space. I manage to do using the property flex-basis: 100%
  • if the width decreases, the search section decreases as well with the property flex-basis: 100%. However, I would like the search section to decrease until 100px and then tabs will decrease displaying ellipsis. I tried using flex-shrink or flex-grow without success since I am not an expert with flexbox.

I reproduced the simplest example in order to illustrate what I am saying.

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 >
  <ul >
    <li>
      <button type="button">Tab Item Number One</button>
    </li>
    <li>
      <button type="button">Tab Item Number Two</button>
    </li>
  </ul>
  <div ></div>
</div>

CodePudding user response:

You need to make use of the power of flex-grow, flex-shrink and flex-basis properties on the children of your flex container.

This is very handy youtube tutorial from Kevin Powell explaining these properties and other important flex-box concepts.

Anyway, here's a solution to your problem with comments explaining what has been added and why.

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 >
  <ul >
    <li> Tab Item Number One</li>
    <li>Tab Item Number Two</li>
  </ul>
  <div >Search</div>
</div>

CodePudding user response:

The most important thing an element needs for ellipsis to work is width. Without a width, the browser won't know when the text is actually being cut from its predefined width. I set a width on your container to 100%. Then set each child element (tabs__list and search) to 50%. I also set the li to 50% so each item would take half of that space. However, I still have flex-basis: 100%; so search fills any remaining space.

With this set, you can now just set width: 100%; to your button, which is the defined width it needs so it knows the text is being cut off and it needs to show ellipsis.

Side note: you can still add your min-width: 100px; to search and it will still show ellipsis, but I removed it because it shows a vertical scrollbar.

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 >
  <ul >
    <li>
      <button type="button">Tab Item Number One</button>
    </li>
    <li>
      <button type="button">Tab Item Number Two</button>
    </li>
  </ul>
  <div ></div>
</div>

  • Related