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>
Related
I'm working on an angular/js app using directives and this particular flex-container uses divs(directives) which may contain one or more items. When a directive includes 3 items for the flexbox, if it isn't a perfect fit for all items in that directive, it pushes the entire row down instead of say leaving one on the top line and putting the rest on the 2nd line. It will instead leave an empty space on top and push all 3 to the 2nd line. The reason for directives in this case is for reuse and grouping common functionality together.
To simplify, this demonstrates the issue I'm seeing just with using divs. Looking at the example if you resize the window you'll see that as soon as there is not enough room to fit the 6th bubble, all 3 in that div get pushed to the second row.
example on codepen
dl,
dt,
dd {
/* resetting definition list styling */
margin: 0;
padding: 0;
}
.bubble {
display: block;
border-radius: 1rem;
background: rgb(52, 58, 64);
color: rgb(255, 255, 255);
text-align: center;
font-weight: 600;
padding: 1rem;
width: 10rem;
height: 10rem;
}
.flex-container {
display: inline-flex;
flex-wrap: wrap;
}
.flex-container div {
display: inline-flex;
}
<div class="flex-container">
<div>
<dl class="bubble">1</dl>
</div>
<div>
<dl class="bubble">2</dl>
</div>
<div>
<dl class="bubble">3</dl>
</div>
<div>
<dl class="bubble">4</dl>
<dl class="bubble">5</dl>
<dl class="bubble">6</dl>
</div>
</div>
Is it possible for me to get that div with 3 items to start after the 3rd bubble and wrap only those that don't fit to the second line?
update:
Use
.flex-container div {
display: contents;
}
Instead of
.flex-container div {
display: inline-flex;
}
display: contents basically ignores the element and makes the element's parent, or flex-container in this case, the parent of the children or the dl tags here. This only affects the layout. The children still keep any of the styling inherited from their wrapper element.
Showing Roya's suggestion here which does the trick...
dl, dt, dd {
/* resetting definition list styling */
margin: 0;
padding: 0;
}
.bubble {
display: block;
border-radius: 1rem;
background: rgb(52, 58, 64);
color: rgb(255, 255, 255);
text-align: center;
font-weight: 600;
padding: 1rem;
width: 10rem;
height: 10rem;
margin-right: 2rem;
margin-top: 1rem;
}
.flex-container {
display: inline-flex;
flex-wrap: wrap;
}
.flex-container div {
display: contents;
}
<div class="flex-container">
<div><dl class="bubble">1</dl></div>
<div><dl class="bubble">2</dl></div>
<div><dl class="bubble">3</dl></div>
<div><dl class="bubble">4</dl></div>
<div>
<dl class="bubble">5</dl>
<dl class="bubble">6</dl>
<dl class="bubble">7</dl>
</div>
</div>
i was using grid property to build web site. but i got a problem that i can't use background property as i expect.
#wrap {
height: 100%;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 35px 125px;
}
.line1 {
width: 1px;
height: 16px;
background: #ccc;
}
header {
background-color: #221816;
grid-column: 2/12;
}
header .topNav {
color: #fff;
}
header .topNav ul {
height: 35px;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
header .topNav ul li {
align-self: center;
padding-right: 16px;
}
*,
:before,
:after {
margin: 0;
padding: 0;
border: 0;
color: #fff;
list-style: none;
}
<div id="wrap">
<header>
<nav class="topNav">
<ul>
<li>login</li><span class="line1"></span>
<li>signin</li>
<li>bags</li>
<li>mypages<span></span></li>
<li>customer</li>
</ul>
</nav>
</header>
</div>
i expected the header's width 100%. so i put 'grid-column:1/-1;' and i got problem that contents have to be narrow. so i fix property like 'grid-column:2/12' then now i got a problem the background can't be wide. do i have solution?
change your header to read: header{background-color:#221816; grid-column: 1/13;}
This is why: You have 12 divisions along the width of your page, but you don't count the area by divisions, you count by the line.Take a piece of scratch paper, draw three lines from side to side, then 13 lines top to bottom to represent your 12 columns and 2 rows of your header/navigation area. Now, the three lines across are numbered 1, 2, and 3 (one at the top, two in the middle, three at the bottom). The 13 verticle lines start with line number one, and if you count all the way across end with line number 13. So, to get your header to go from one side of the page to the other, it needs to start on line 1 and end on line 13 (1/13). Does that make sense?
If I understand correctly what you're trying to do, you can get what you want with a lot less effort, as I've shown below. Just do this row with flex. You don't need to use grid.
After I wrote up this answer, your subsequent comments say that you want to do something that you haven't shown us with some more rows that are different from this one. You can do things the way I've shown you for this row, and then add another div with the grid in it and do what you want with it.
If that doesn't work for you, then you'll need to further clarify what you're trying to do.
.line1 {
width: 1px;
height: 100%;
background: #ccc;
}
header {
background-color: #221816;
}
header .topNav {
color: #fff;
}
header .topNav ul {
height: 35px;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
header .topNav ul li {
padding: 0 2%;
align-self: center;
}
*,
:before,
:after {
margin: 0;
padding: 0;
color: #fff;
list-style: none;
}
<div id="wrap">
<header>
<nav class="topNav">
<ul>
<li>login</li><span class="line1"></span>
<li>signin</li>
<li>bags</li>
<li>mypages<span></span></li>
<li>customer</li>
</ul>
</nav>
</header>
</div>
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'd like scrolling content underneath a variable-height element. Is this a CSS blind spot or am I just not thinking of an obvious solution?
Codepen with my best effort so far, but it only works in Chrome and Firefox:
http://codepen.io/anon/pen/BKpxGP
HTML:
<div class="sidebar">
<header>
<h1>Header content that I would like to remain on the screen even when the main area is scrolled down.</h1>
<p>I want to avoid specifying a height or top padding/margin value, as the content may grow or shrink at times.</p>
<p>This code seems to work in Chrome and Firefox but not in Safari. I haven't tested IE yet.</p>
<p><strong>Challenge:</strong> Can we make it cross-browser?</p>
</header>
<main>
<ul>
<li>Elephant</li>
<li>Giraffe</li>
<li>Otter</li>
<li>Nine-banded armadillo</li>
<li>Cat</li>
</ul>
</main>
</div>
CSS:
.sidebar {
width: 400px;
height: 700px;
border: 10px solid #808080;
margin: auto;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
.sidebar header {
background-color: #87ceeb;
border-bottom: 10px solid #00f;
padding: 0 1em;
}
.sidebar header h1 {
font-size: 1.2rem;
}
.sidebar main {
overflow-y: auto;
-webkit-flex-basis: auto;
-ms-flex-preferred-size: auto;
flex-basis: auto;
-webkit-box-flex: 1;
-webkit-flex-grow: 1;
-ms-flex-positive: 1;
flex-grow: 1;
-webkit-flex-shrink: 1;
-ms-flex-negative: 1;
flex-shrink: 1;
}
.sidebar main li {
height: 400px;
border-right: 10px solid #ffc0cb;
margin: 10px;
padding: 10px;
}
it much more easy than you thought i think.
The css code that you are searching for is:
.example {
position: fixed;
}
On my website you see the same result in the header section. It stays on the top, even if you are scrolling down. :)
I think this is what you want http://codepen.io/dirtysmith/pen/jqyKBO
css
.sidebar header {
background-color: #87ceeb;
border-bottom: 10px solid #00f;
padding: 0 1em;
position: fixed;
width: 368px;
}
added a width to match the container, and position fixed.
I tried this today, and Safari works fine. I guess its Flex support was lagging but it's fixed now. Thank you for the suggestions everyone!
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>