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.
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 usingflex-shrink
orflex-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>