On a simple flex-box layout, I am trying to align nav items to the end of the first (left) side-bar. My first thought was to recreate the aside main aside layout with :before element :after so the nav items would always align to the sidebar, but I can't seem to get the :before and :after elements to match the size of each aside. Here is an example of what I am trying to do
Flex Example
And here is the current code I am using
http://codepen.io/anon/pen/GoJEbX?editors=010
I wouldn't be using flex-wrapping rows here. It makes sense to start with flex-direction:column to get the full 100% height and then put the middle content (main and aside elements) in their own flex-container which can then grow as much as is required.
The horizontal layout is all flexbox.
Based on the original code the aside are 1/12th wide each (flex:1) while the main is 10/12ths (flex:10).
Therefore to line up the menu with the main, the menu itself needs to be shifted over the same amount (which means it's 11/12ths [flex:11] so the pseudo-element is just flex:1.
Adjust as required.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
body {
min-height: 100%;
}
.wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
nav {
display: flex;
}
nav:before {
content: '';
flex: 1;
background: plum;
/* for reference */
}
nav ul {
display: flex;
background: blue;
list-style-type: none;
flex: 11;
}
nav ul a {
display: block;
padding: 20px 20px 0 0;
color: white;
text-decoration: none;
}
.content {
flex: 1;
display: flex;
}
main {
background: red;
flex: 10;
}
aside {
background: green;
flex: 1;
}
footer {
background: yellow;
}
<div class="wrapper">
<header>
<nav>
<ul>
<li>Item 1
</li>
<li>Item 2
</li>
<li>Item 3
</li>
</ul>
</nav>
</header>
<div class="content">
<aside>Sidebar 1</aside>
<main>Main Content Area</main>
<aside>Sidebar 2</aside>
</div>
<footer>Footer</footer>
</div>
Codepen Demo
Related
This question already has answers here:
Align 3 unequal blocks left, center and right
(4 answers)
Closed 3 years ago.
I am creating simple navigation with flexbox CSS3 and I have a list with 3 items but those items have not specified width. Now I want to have the middle item to be placed in the center of the viewport. When I have that kind of situation my middle li is not centered on the viewport. Is there any way to center one item and other elements to be relative to this item?
See the differences between first and second navigation. On second navigation when there is one item it's properly centered to the viewport. I want to center the first one like second. Li element with class middle must be at the center of the viewport.
EDIT
Some of the answers did the typical moving first and last LI to the edges of the UL LIST. That's not the point, MIDDLE li must be at the center of the viewport and first and last LI should have only paddings and width: initial
ANSWER
I cannot add answer here so I paste 'codepen' link with answer which I want to get
https://codepen.io/freestyle09/pen/xxxvwPm
UPDATED CODE
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
nav {
border: 1px solid red;
display: flex;
justify-content: center;
}
ul {
display: flex;
justify-content: center;
list-style: none;
border: 1px solid green;
width: 1200px;
}
ul > li {
padding: 20px;
white-space: nowrap;
border: 1px solid blue;
}
li:not(.middle) {
flex-basis: 0%;
flex-grow: 1;
}
nav .test {
display: flex;
justify-content: center;
width: 800px;
border: 2px solid pink;
padding: 20px
}
<nav>
<ul>
<li><span>Lorem ipsum sit</span></li>
<li><span>Lorem ipsum sit</span></li>
<li class='middle'><span>Vey long string, very very very long string</span></li>
<li><span>About</span></li>
<li><span>About</span></li>
</ul>
</nav>
<nav>
<div class='test'>
<p>Vey long string, very very very long string</p>
</div>
</nav>
I'm not entirely sure I understand what you're trying to accomplish but this sounds like maybe what you're after?
Addendum, you just described the purpose of a table for tabular data. Hope this helps, cheers!
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
nav {
border: 1px solid red;
}
ul {
display: table;
width: 100%;
list-style: none;
align-items: center;
border: orange 3px dashed;
}
ul > li {
display: table-cell;
text-align: center;
padding: 20px;
border: green 1px dotted;
}
ul > li:nth-child(odd) {
width: 20%;
}
<nav>
<ul>
<li>Lorem ipsum sit</li>
<li class='middle'>Vey long string, very very very long string</li>
<li>About</li>
</ul>
</nav>
<nav>
<ul>
<li>Vey long string, very very very long string</li>
</ul>
</nav>
On way to approach this is to give the li.middle element a higher flex-grow priority and a lower flex-shrink priority than the other li elements.
The style flex is a shorthand for:
flex-grow
flex-shrink
flex-basis
It will take flex values such as these:
flex: 1 1 20%; // flex-grow priority of 1, flex-shrink priority of 1, pre-flex starting width of 20%
flex: 2 0 60%; // flex-grow priority of 2, will never shrink, pre-flex starting width of 60%
Using these two values above we can declare that:
one class of element has a default width of 20% and can both grow and shrink to fill the width available
another class of element has a default width of 60%, is twice as likely to grow wider than the other elements, but can never shrink to less than 60%
Working Example:
nav {
border: 1px solid red;
}
ul {
display: flex;
list-style: none;
justify-content: center;
border: 1px solid green;
margin-left: 0;
padding-left: 0;
}
ul > li {
padding: 20px;
}
li {
border: 1px solid blue;
}
li {
flex: 1 1 20%;
}
li.middle {
flex: 2 0 60%;
text-align: center;
}
<nav>
<ul>
<li>Lorem ipsum sit</li>
<li class="middle">Very long string, very very very long string</li>
<li>About</li>
</ul>
</nav>
<nav>
<ul>
<li class="middle">Very long string, very very very long string</li>
</ul>
</nav>
Adding the following properties to your style should fix your problem.
ul > li {
padding: 20px;
flex: 1;
text-align: center;
}
That will set all the li element sizes to be equal and align their text to the center of it.
I'm attempting to learn flexbox and I'm trying to achieve the following layout.
+----------+----------+
| |nav |
| header +----------+
| |section |
+----------+----------+
HTML Structure
<header></header>
<nav></nav>
<section></section>
Layout Requirements
Width of each element is exactly 50vw (or 50%)
Header content is always centered and fixed. Takes up 100vh.
Nav content is fixed
Section content is scrollable, overflow is hidden.
Is this even possible with flexbox?
On mobile devices, I want to have all three in a column but that part is easy.
body {
display: flex;
flex-flow: column wrap;
height: 100vh; /* key rule; this tells flex items where to wrap
to form second column */
}
header {
flex: 0 0 100%;
width: 50%;
/* center content */
display: flex;
justify-content: center;
align-items: center;
}
nav, section {
flex: 0 0 50%;
width: 50%;
}
/* non-essential decorative styles */
* { box-sizing: border-box; margin: 0; }
header { background-color: aqua; }
nav { background-color: tomato; }
section { background-color: lightgreen; }
<header>header</header>
<nav>nav</nav>
<section>section</section>
For a detailed explanation and alternative methods see my answer here:
Is it possible for flex items to align tightly to the items above them?
if you want to use flexbox you can get away with doing a dual container layout.
HTML
<div class="flex-container">
<header>Something</header>
<div class="flex-child-container">
<nav>nav</nav>
<section>section</section>
</div>
</div>
CSS
div {
display: flex;
width: 100%;
height: 100%
}
.flex-child-container {
flex-direction: column;
}
I have a layout with left and right canvas sidebars, enclosing the Main content area in the middle.
The sidebars and main content are flex items, positioned in a flex layout left to right.
The sidebars contain menus and meta links.
My question is: when scrolling the content area, is it possible to leave the sidebars in fixed position, such that they stay in top position and do not scroll down?
JS Fiddle: http://jsfiddle.net/Windwalker/gfozfpa6/2/
HTML:
<div class="flexcontainer">
<div class="flexitem" id="canvas-left">
<p>This content should not scroll</p>
</div>
<div class="flexitem" id="content">
<div>
<p>Scrolling Content</p>
</div>
</div>
<div class="flexitem" id="canvas-right">
<p>This content should not scroll</p>
</div>
</div>
CSS:
.flexcontainer {
display: flex;
flex-direction: row;
min-height: 100%;
align-items: stretch;
}
.flexitem {
display: flex;
}
#canvas-left {
background: yellow;
order: -1;
flex: 0 0 57px;
}
#content {
background: green;
order: 1;
padding: 1rem;
}
#content div {
display: block;
}
#canvas-right{
background: blue;
order: 2;
flex: 0 0 57px;
}
Please look at the similar question with provided solution: How to simulate 'position:fixed' behavior on Flexbox-aligned sidebar.
According to your code you can also wrap your inner content in "position: fixed" wrapper:
<div class="flexitem" id="canvas-left">
<div class="fixed">
<p>This content should not scroll</p>
</div>
</div>
And add proper styling in CSS:
.fixed {
position: fixed;
width: 57px; /* according to #canvas-left */
}
Here is an example of your code with fixed left sidebar: http://jsfiddle.net/8hm3849m/. Note that this trick won't provide you proper flexible grid for sidebars, width of the wrapper should be fixed (or set dynamically via JavaScript).
The question is old, but I solved a similar issue using
position: sticky;
top: 0;
for the left and right items.
Also I removed the
display: flex
css for the flex items, I don't think that's necessary.
https://jsfiddle.net/8mpxev0u/
i dont know how do it with flex, but here is a easyer/alternate css remove all that flex... and try to never add padding to a outer div, its easyer in inner items, then you dont need to calculate if there are to many divs
.flexcontainer {
display: block;
min-height: 100%;
align-items: stretch;
}
.flexitem {
display: flex;
}
#canvas-left {
background: yellow;
order: -1;
left: 0px;
width: 20%;
position: fixed;
}
#content {
position: absolute;
background: green;
order: 1;
width: 60%;
left: 20%;
}
#content p {
display: block;
padding: 1rem;
}
#canvas-right{
background: blue;
order: 2;
right: 0px;
width: 20%;
position: fixed;
}
I have an html page structure like this:
<div id="list">
<ul>
<li style="background-color:orange;">Lorem</li>
<li style="background-color:red;">Lorem</li>
.............
<li style="background-color:black;">Lorem</li>
<li style="background-color:blue;">Lorem</li>
</ul>
</div>
On this page, I want all list element to have the same width - I don't care about the content, only the color is really important in this case - and I want all thos elements to fit in their parent div (#list) when the page just loaded, this mean no scroll.
And this list is not final, I can add or delete somme elements in my list after the page load. I would like to know if there is a CSS way to get this result, JavaScript is not really suitable in this case.
Is that possible ?
You can achieve this kind of behavior by using flex:
HTML structure:
<div id="list">
<ul>
<li style="background-color:orange;">Lorem</li>
<li style="background-color:black;">Lorem</li>
...
<li style="background-color:blue;">Lorem</li>
</ul>
</div>
CSS:
#list {
border-style: solid;
border-width: 3px;
white-space: nowrap;
}
#list ul {
display: flex;
flex-direction: row;
margin: 5px;
padding: 0;
}
#list ul li {
border-style: solid;
height: 50px;
list-style-type: none;
}
Here is a working demo: http://jsfiddle.net/kmbxawdd/1/
Yes, you can use flexible boxes:
#list {
display: flex; /* Magic begins */
border: 3px solid;
padding: 1em;
}
#list > li {
width: 0; /* Ignore the width of the content */
flex-grow: 1; /* Distribute remaining space equally */
overflow: hidden; /* Hide possible overflow */
height: 50px;
border-style: solid;
}
<ul id="list">
<li style="background-color:orange;">Lorem</li>
<li style="background-color:red;">Lorem</li>
<li style="background-color:black;">Lorem</li>
<li style="background-color:blue;">Lorem</li>
</ul>
JSFiddle Example
Flexbox is your friend.
div#list {
height: 800px; /*Whatever you want, really*/
width: 800px; /*Again, substitute this with whatever size you like*/
}
div#list ul {
height: 100%;
width: 100%;
display: flex;
flex-flow: row nowrap;
align-content: stretch;
list-style: none;
padding: 0;
margin: 0;
}
div#list ul li {
-webkit-flex: 0 1 100%;
flex: 0 1 100%;
}
You can try to set display to "table" on list and "table-cell" on li. But it will work as you expect only if all li elements will contain content with same width. And list itself must have explicitly defined width, of course.
I'm having trouble using CSS3 flex display and overflow.
I'd like a box to be "y-scrollable" if contents overflow on y-axis and "x-overflowed" if content overflows on x-axis.
I found this codepen illustrating how to set the box y-scrollable and I forked this one to illustrate my problem.
As you can see (using Chrome), a x-scrollbar is added even if overflow-x is set to visible. I hoped content would overflow upon the y-scrollbar and be visible without x-scrollbar...
Any solution ?
The base HTML code is
<ul>
<li><div>Item</div></li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
The base CSS code is
ul {
flex: 1;
min-height: 0;
overflow: auto;
}
And, to make trouble, replace by
ul {
flex: 1;
min-height: 0;
overflow-x: visible ;
overflow-y: auto;
}
div{
background-color : red ;
width : 150% ;
}
For make it really revealant, add
ul {
list-style: none;
margin: 0;
padding: 0;
background: hsl(200,100%,90%);
}
li { padding: 20px; }
li:nth-child(odd) { background: hsl(200,100%,85%); }
header, footer { padding: 20px; background: hsl(0,0%,70%); }
body {
display: flex;
/* doesn't work without prefix */
-webkit-flex-flow: column;
flex-flow: column;
height: 100%;
box-sizing: border-box;
padding: 20px;
background: hsl(0,0%,80%);
}
html { height: 100%; }
I could be reading this wrong, but if you're not wanting there to be a horizontal scroll bar, then you can set overflow-x: hidden; and it should be okay.