https://codepen.io/fluark/pen/VwxGawr
.header {
display: flex;
font-family: monospace;
background: papayawhip;
align-items: center;
justify-content: space-between;
margin-left: auto;
}
ul {
display: flex;
background: papayawhip;
gap: 10em;
list-style-type: none;
flex-direction: row;
margin: 0;
padding: 0;
}
Desired Outcome
Visually my header looks fairly close to the desired outcome, however when I shrink down the page, the right links/ul (child items) spill out of the header (parent).
I am pretty sure this is a matter of not having the proper flex settings. Is the error maybe in the flex-basis? Or potentially the relationship between flex-shrink and flex-basis?
I have looked up flex settings and tried separately adding “flex: 1;” on both the parent .header as well as the div.right-links and ul.
I have also tried creating a separate div... div.header and then adding flex: 1 to that with the intention of making it so the parent is able to grow when the window is resized. That didn't seem to do anything.
I am a little confused because with “display: flex” on both the .header element and the ul, that means the flex-shrink is 1 (flex = 0, 1, auto), so shouldn’t the links be shrinking when the parent element is resized, not spilling out?
I’m looking for some guidance/talk throughs because I am at the point where I am just adding to the code to “see what happens”, and that’s when I know I need help.
Thanks in advance!
The ul element has a default padding of 26px and when you narrow the viewport it's that padding that's pushing the div to the right. If you set padding-left: to 0 then it removes it. I've also set the li display type to inline-block so that the padding on the a element does not overflow the logo on small screen sizes. At really small screen sizes (below 612px or so), the logo, a tags, gaps and padding will all be the lowest they can be so if you want to restyle it any further then I'd use a media query. See below
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
font-family: monospace;
background: papayawhip;
padding: 5px;
}
.logo {
font-size: 48px;
font-weight: 900;
color: tomato;
background: white;
padding: 4px 32px;
}
ul {
padding-left: 0;
display: flex;
gap: 1em;
flex-direction: row;
/* this removes the dots on the list items*/
list-style-type: none;
}
li {
display: inline-block;
}
a {
font-size: 22px;
background: white;
/* this removes the line under the links */
padding: 8px;
text-decoration: none;
}
<div class="header">
<div class="left-links">
<ul>
<li>ONE</li>
<li>TWO</li>
<li>THREE</li>
</ul>
</div>
<div class="logo">LOGO</div>
<div class="right-links">
<ul>
<li>FOUR</li>
<li>FIVE</li>
<li>SIX</li>
</ul>
</div>
</div>
This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
Closed 5 years ago.
It seems that when using flex with nowrap - the scroll bar allows moving only to the right but the items on the left remain hidden.
I've created a doceopen example to show the problem.
http://codepen.io/anon/pen/QpgvoZ
In the following case, it seems that the horizontal scroll bar only works to the right but the items on the left are simply hidden and not reachable.
I see this behavior in Chrome and FF (IE11 seems to be working properly :-O )
What I'm missing here?
Thanks!
#import "compass/css3";
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row nowrap;
justify-content: space-around;
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
min-width: 200px;
height: 150px;
margin-top: 10px;
flex-shrink: 0;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
<ul class="flex-container">
<li class="flex-item">111111</li>
<li class="flex-item">222222</li>
<li class="flex-item">333333</li>
<li class="flex-item">444444</li>
<li class="flex-item">555555</li>
<li class="flex-item">666666</li>
<li class="flex-item">777777</li>
<li class="flex-item">888888</li>
<li class="flex-item">999999</li>
</ul>
can you remove
-webkit-flex-flow: row nowrap;
justify-content: space-around;
and add overflow-x:auto; to .flex-container
it seems like solves your problem
This question already has answers here:
Chrome / Safari not filling 100% height of flex parent
(5 answers)
Closed 6 years ago.
I ran into a problem where a ul element is not displayed at 100% height of it's parent in safari. I understand that it's not a new problem and might have been answered here before but I couldn't find an answer that would be close to my specific problem, most of them are about a div not being 100% of the whole page etc.
Here is how it looks in Chrome (this is the result that I want):
And here is how it looks in Safari:
Here is the css:
.container {
display: flex;
flex-flow: row wrap;
}
.header {
min-height: 60px;
border: 1px solid #000;
}
.list {
height: 100%;
display: flex;
justify-content: flex-start;
list-style: none;
margin: 0;
padding: 0;
}
li {
padding: 10px;
background-color: #cecece;
}
Note that the rest of the css in .list class is needed for my application.
Please check out the Jsfiddle
Cheers!
.container {
display: flex;
flex-flow: row wrap;
}
.header {
min-height: 60px;
border: 1px solid #000;
}
.list {
height: 100%;
display: flex;
justify-content: flex-start;
list-style: none;
margin: 0;
padding: 0;
background-color: #cecece;
}
li {
padding: 10px;
background-color: #cecece;
}
<div class="container">
<div class="header">
<ul class="list">
<li>
Donald
</li>
<li>
Hillary
</li>
<li>
Gary
</li>
</ul>
</div>
</div>
Try to add normalize.css to your code (in jsfiddle you can do this just from the css options) then try safari and it should works.
I have been attempting to use flexbox for this, but any other css-only solution would be acceptable.
I want all items along a row to expand to the width of the largest item, so the result is identical widths. However, at the same time without the parent element expanding beyond the minimum size needed to accomplish this.
If you look at my Codepen example, altering the flex-grow value on <ul> elements will make this work for some of the demo examples, but not all.
http://codepen.io/MattyBalaam/pen/VepxWq
div {
display: flex;
justify-content: center;
}
ul {
display: flex;
justify-content: center;
padding: 0 0 2em;
flex-grow: 0.15;
}
li {
list-style: none;
margin: 2em;
flex: 1 1 0;
}
<div>
<ul>
<li>1</li>
<li>2</li>
<li>----3----</li>
</ul>
</div>
I have a horizontal flex box (i.e. flex-direction: row, i.e. side-by-side) with a few items. Each item can be a single line of text, or can have multiple lines. I want to vertically-align the contents of each flex item.
If each item had a transparent background, I could easily use align-items: center. However, I want each item to be stretched vertically, because I want to set a background (or maybe borders, or maybe it is a clickable region) to the entire available height.
So far, I know:
Stretching: align-items: stretch
Aligning: align-items: center
Stretching and aligning: ???
Demo available at http://codepen.io/denilsonsa/pen/bVBQNa
ul {
display: flex;
flex-direction: row;
}
ul.first {
align-items: stretch;
}
ul.second {
align-items: center;
}
ul > li {
flex-grow: 1;
flex-shrink: 0;
flex-basis: 5em;
text-align: center;
}
ul > li:nth-child(2) {
background: #CFC;
}
/* Visual styles, just ignore. */
html, body { font-family: sans-serif; font-size: 25px; }
ul, li { list-style: none; margin: 0; padding: 0; }
ul { background: #CCF; width: 25em; }
<ul class="first">
<li>Sample</li>
<li><span>span</span></li>
<li><span>multiple</span> <span>span</span></li>
<li>text <span>span</span></li>
<li>multi<br>line</li>
</ul>
<hr>
<ul class="second">
<li>Sample</li>
<li><span>span</span></li>
<li><span>multiple</span> <span>span</span></li>
<li>text <span>span</span></li>
<li>multi<br>line</li>
</ul>
Similar questions:
Question 14012030 and question 23442692 and question 27729619 and question 25311541 ask essentially the same thing, but they either have a single element or plain text as child of each flex item. As soon as we have mixed content, possibly with multiple elements, those solutions do not work.
Question 19026884 is unrelated, the issue there was the wrong markup.
Unfortunately, it is impossible to achieve the desired effect while using the exact markup posted in the question.
The solution involves:
Setting display: flex; on <li>.
Wrapping the <li> contents into another element.
This is required because <li> is now a flex container, so we need another element to prevent the actual contents from becoming flex items.
In this solution, I introduced a <div> element, but it could have been other element.
Now that <li> is a flex container and it contains only a single child, we can use align-items and/or justify-content to align this new and only child.
The DOM tree looks like this:
<ul> flex-parent, direction=row
├ <li> flex-item && flex-parent && background && JavaScript clickable area
│ └ <div> flex-item as a single transparent element
│ ├ Actual contents
│ └ Actual contents
├ …
Note: The solution in this answer uses 2 nested flex boxes. The solution by Michael_B uses 3 nested flex boxes, because it has the added challenge of expanding the <a> element to fill the entire <li>. Which one is preferred depends on each case. If I could, I would accept both answers.
/* New code: this is the solution. */
ul > li {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
/* Old code below. */
ul {
display: flex;
flex-direction: row;
align-items: stretch;
}
ul > li {
flex-grow: 1;
flex-shrink: 0;
flex-basis: 5em;
text-align: center;
}
ul > li:nth-child(2) {
background: #CFC;
}
/* Visual styles, just ignore. */
html, body { font-family: sans-serif; font-size: 25px; }
ul, li { list-style: none; margin: 0; padding: 0; }
ul { background: #CCF; width: 25em; }
button:focus + ul {
font-size: 14px;
width: auto;
}
<button>Click here to set <code>width: auto</code> and reduce the font size.</button>
<!-- New code: there is a single <div> between each <li> and their contents. -->
<ul>
<li><div>Sample</div></li>
<li><div><span>span</span></div></li>
<li><div><span>multiple</span> <span>span</span></div></li>
<li><div>text <span>span</span></div></li>
<li><div>multi<br>line</div></li>
</ul>
I want each item to be stretched vertically, because I want to set a
background (or maybe borders, or maybe it is a clickable region) to
the entire available height.
You can achieve this layout without any changes to your HTML structure. There's no need for additional containers.
You already have a primary flex container and a group of flex items. Simply make those flex items into nested flex containers. That will enable you to align the content with flex properties.
(Since you mentioned that you may need clickable regions, I switched from li to a elements.)
nav {
display: flex;
background: #CCF;
width: 25em;
}
nav > a {
flex: auto; /* flex-grow: 1, flex-shrink: 1, flex-basis: auto */
text-align: center;
text-decoration: none;
display: flex;
align-items: center;
justify-content: center;
}
nav > a:nth-child(2) {
background: #CFC;
}
html, body {
font-family: sans-serif;
font-size: 25px;
}
<nav>
Sample
<span>span</span>
<span>multiple</span> <span>span</span>
text <span>span</span>
multi<br>line
</nav>
revised codepen
Note that content placed directly inside a flex container is wrapped in an anonymous flex item:
From the spec:
4. Flex Items
Each in-flow child of a flex container becomes a flex item, and each contiguous run of text that is directly contained inside a flex
container is wrapped in an anonymous flex item.
So, because the text is automatically wrapped in flex items, you can keep the full height of each item (align-items: stretch from the primary container) and vertically center the content (align-items: center from the nested containers).
Make the li flex-containers with flex-direction:column. I think that's what you are after.
html,
body {
font-family: sans-serif;
font-size: 25px;
}
ul,
li {
list-style: none;
margin: 0;
padding: 0;
}
ul {
background: #CCF;
width: 25em;
display: flex;
flex-direction: row;
}
ul.first {
align-items: stretch;
}
ul > li {
flex-grow: 1;
flex-shrink: 0;
flex-basis: 5em;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
/*outline: 1px dotted #444;*/
}
ul > li:nth-child(2) {
background: #CFC;
}
<ul class="first">
<li>Sample</li>
<li><span>span</span>
</li>
<li><span>multiple</span> <span>span</span>
</li>
<li>text <span>span</span>
</li>
<li>multi
<br>line</li>
</ul>
Flex-child items can also be flex-parent items.
*,
*:before,
*:after {
box-sizing: inherit;
}
html {
box-sizing: border-box;
font-family: sans-serif;
font-size: 25px;
}
body {
display: flex;
flex-flow: column nowrap;
background-color: #333;
overflow: hidden;
}
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
.List {
padding: 0;
margin: 0;
background: #CCF;
width: 25em;
list-style: none;
display: flex;
flex-flow: row nowrap;
justify-content: center;
}
.ListItem {
flex-basis: 5em;
display: flex;
flex-flow: row wrap;
text-align: center;
align-items: center;
}
.ListItem:nth-child(2) {
background: #CFC;
}
.ListItem__content {
width: 100%;
}
<ul class="List">
<li class="ListItem">
<span class="ListItem__content">Sample</span>
</li>
<li class="ListItem">
<span class="ListItem__content">span</span>
</li>
<li class="ListItem">
<span class="ListItem__content">multiple <br> span</span>
</li>
<li class="ListItem">
<span class="ListItem__content">span</span>
</li>
<li class="ListItem">
<span class="ListItem__content">multi<br>line</span></li>
</ul>