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
Related
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>
So I'm having a problem centering items from a menu I'm making.
I have tried to put justify-content: center but that does not seem to work. Can someone help?
Right now the menu is stuck on the left corner. I want to center it.
.header2 {
background-color: rgb(190, 13, 13);
display: flex;
flex-wrap: wrap;
align-items: center;
padding: 15px;
}
.menu {
display: flex;
}
.menu li {
margin-right: 15px;
}
.menu li a {
display: block;
padding: 10px;
}
<nav class="header2">
<ul class="menu">
<li>Home</li>
<li>About</li>
<li>Products</li>
<li>Contacts</li>
</ul>
</nav>
The nested flexbox (.menu) is set, by default, to flex-grow: 0, which means it won't occupy the full length of the parent.
Therefore, applying justify-content: center has no effect because there's no free space available in the container.
Adding flex-grow: 1 provides the extra space you need:
Add this to your code:
.menu {
display: flex;
flex: 1;
justify-content: center;
}
Also, since you're already using the semantically meaningful nav element, there's really no need for a nested list element. Try this simplified code instead:
.menu {
display: flex;
justify-content: center;
background-color: rgb(190, 13, 13);
}
.menu a {
padding: 25px 10px;
}
.menu a:hover {
background-color: orangered;
}
<nav class="menu">
Home
About
Products
Contacts
</nav>
Try:
.menu {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
flex-grow: 1; /* or width: 100% */
}
if you want the elements evenly distributed by all the width.
And:
.menu {
display: flex;
flex-wrap: wrap;
justify-content: center;
flex-grow: 1; /* or width: 100% */
}
otherwise.
Pen here.
HTML
<header>
<div id="logo-div">
MyLogo
</div>
<nav>
<ul class="nav-list">
<li class="item">LINK #1</li>
<li class="item">LINK #2</li>
<li class="item">LINK #3</li>
<li class="item">LINK #4</li>
<li class="item">LINK #5</li>
</ul>
</nav>
</header>
CSS
header{
display: inline-block;
width: 90%;
}
#logo-div{
margin-right: 50px;
float: left;
font-size: 28px;
color: red;
font-weight: 800;
line-height: 60px;
}
nav{
float: right;
}
.nav-list{
display: flex;
height: 150px;
width: auto;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: flex-start;
align-content: flex-start;
margin: 0%;
padding: 0%;
width: auto;
list-style-type: none;
}
.item{
background-color: #d6315d;
height: 50px;
width: 150px;
margin: 5px;
text-align: center;
line-height: 45px;
font-weight: 600;
}
Typical website header with inline-block display, logo div on left and navbar on right.
I need to have flex-wrapping navbar to accommodate various device widths, at least until screen-width = 600px where it can be changed to a hamburger. So I make the nav-list height 3 times the height of the list item.
Problem is that if I float the nav block to the right within the header, the nav item-list will only wrap UNDER the logo-div, not beside it.
I can solve this by removing the float from the nav block altogether. But now the nav block drifts to the left on zoom, so the whole page looks off-center.
Anyone got any ideas ?
EDIT
This CodePen achieves the desired effect of stacking nav items on rows within a navbar without the navbar spilling below the logo - at least till screen widths go below ~ 400px.
If I understand correctly you are having an issue with the items not being aligned when the screen is smaller. The best way to do this is using display: flex to get alignment done easily. I have done a sample code and hope it helps your problem (align-items-center aligns all items including your logo to the center in the row when the screen size changes. If you don't need it you can remove it)
HTML
<header>
<div class="d-flex flex-row align-items-center">
<div class="logo">
MyLogo
</div>
<nav>
<ul class="nav-list">
<li class="item">LINK #1</li>
<li class="item">LINK #2</li>
<li class="item">LINK #3</li>
<li class="item">LINK #4</li>
<li class="item">LINK #5</li>
</ul>
</nav>
</div>
</header>
CSS
.nav-list {
display: flex;
width: auto;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
margin: 0%;
padding: 0%;
list-style-type: none;
}
.item {
background-color: #d6315d;
height: 50px;
width: 150px;
margin: 5px;
text-align: center;
line-height: 45px;
font-weight: 600;
}
.d-flex {
display: flex;
}
.flex-row {
flex-direction: row;
}
.align-items-center {
align-items: center;
}
.logo {
margin-right: 50px;
font-size: 28px;
color: red;
font-weight: 800;
}
JS Fiddle Link: https://jsfiddle.net/SJ_KIllshot/7u36m194/
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 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>