I need to clear flex box layout item so that first item is 100% width, the second is 50% centered on its own line, and 3rd and 4th are 50% width on the same line.
The clear works normal on simple block items but I can't find a way to do this with flex layout.
https://jsfiddle.net/tzx8qyjt/
.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 wrap;
justify-content: space-around;
}
.item {
background: tomato;
padding: 5px;
width: 100%;
height: 150px;
margin-top: 10px;
margin-bottom: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
.container.block {
display: block;
}
.container.block .item {
float: left;
box-sizing: border-box;
}
.half {
width: 50%;
}
.container .item.centered {
float: none;
clear: both;
margin-left: auto;
margin-right: auto;
}
<ul class="container">
<li class="item">1</li>
<li class="item half centered">2 Clear after me</li>
<li class="item half">3</li>
<li class="item half">4</li>
</ul>
<br />
<br />
<br />
<br />
<br />
<ul class="container block">
<li class="item">1</li>
<li class="item half centered">2 Clear after me</li>
<li class="item half">3</li>
<li class="item half">4</li>
</ul>
Since clearing floats won't work the same for flex items, you could do like this, where you set box-sizing: border-box on all items (makes padding be included in the set width) and then for your 2:nd, you give it a small margin, which will force the rest to a new line
.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 wrap;
justify-content: space-around;
}
.item {
background: tomato;
padding: 5px;
width: 100%;
height: 150px;
margin-top: 10px;
margin-bottom: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
box-sizing: border-box;
}
.half {
width: 50%;
}
.container .item.centered {
margin: 0 10px;
}
<ul class="container">
<li class="item">1</li>
<li class="item half centered">2 Clear after me</li>
<li class="item half">3</li>
<li class="item half">4</li>
</ul>
I hope that it may work for you. I am using this code.
.clear {
width: 100%;
border: none;
margin: 0;
padding: 0;
}
<ul class="container">
<li class="item">1</li>
<li class="item half">2 Clear after me</li>
<li class='clear'><li>
<li class="item half">3</li>
<li class="item half">4</li>
</ul>
What we generally use in flow layout.
.clear {
border: 0;
clear: both;
height: 0;
}
The key to the flex layout is using proper widths, flex-wrap: wrap and box-sizing: border-box.
The first item gets 100% width. That forces subsequent items off the line.
The second, third and fourth items each get 50% width.
But each item also has horizontal padding. So item 2 will force items three and four off the line.
For items three and four, if we adjust their box model from box-sizing: content-box (the default) to border-box, the padding gets included in the width calculation and both items fit perfectly on one line.
.container {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
padding: 0;
margin: 0;
list-style: none;
}
li:nth-child(1) { flex: 0 0 100%;} /* flex-grow, flex-shrink, flex-basis */
li:nth-child(2) { flex: 0 0 50%; }
li:nth-child(3) { flex: 0 0 50%; box-sizing: border-box; }
li:nth-child(4) { flex: 0 0 50%; box-sizing: border-box; }
.item {
background: tomato;
padding: 5px;
height: 150px;
margin-top: 10px;
margin-bottom: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
<ul class="container">
<li class="item">1</li>
<li class="item half centered">2 Clear after me</li>
<li class="item half">3</li>
<li class="item half">4</li>
</ul>
Related
Heeey friends,
I'm trying to do this, I want to change positions of every second post, from left to right.
Here is an example:
I used for the "main-content" the nth-child(even) and it works fine, but for the other div its just doesn't work at all.
CSS:
.archive-cc {
position: relative;
padding-right: 5%;
padding-left: 5%;
width: 100%;
height: 300px;
z-index: 80;
background-color: floralwhite;
border-bottom: pink 10px solid;
}
.archive-content {
position: relative;
float: right;
margin: 0 auto;
width: 80%;
z-index: 50;
background-color: dodgerblue;
}
.archive-cc:nth-child(even)>div {
position: relative;
float: left;
margin: 0 auto;
width: 80%;
z-index: 50;
}
.meta {
float: left;
background-color: yellow;
width: 20%;
}
.meta-text {
width: 100%;
background-color: yellow;
}
.meta:nth-child(even)>div {
float: right;
width: 100%;
background-color: hotpink;
}
HTML:
<div class="archive-cc">
<div class="meta">
<div class="meta-text">PLS WOOOORK</div>
</div>
<div class="archive-content">
<h2 class="entry-title">testtest</h2>
<div class="entry-summary">test</div>
</div>
</div>
I literally tried everything already, I hope someone can help me! It looks like this right now: http://helga-fruehauf-koehler.de/wordpress/fotografie/
I suggest not to use any floating layout here, but flexbox to reach your goal. This is supported by modern browsers and easier to work with.
Found a very good resource on how to split flexbox items into multiple rows at tobiasahlin's blog.
Found a very good explanation on flex-direction on css-tricks. This also includes an Codepen example using different CSS classes per flex-direction.
Here is my solution using the nth-child pseudo class which abstracts away the .row and .row-reverse CSS classes from example above.
Demo: https://jsfiddle.net/vp8xbqus/1/
Code:
HTML
<div class="wrapper">
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
</ul>
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
</ul>
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
</ul>
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
</ul>
<!-- add more boxes as above -->
</div>
CSS
.wrapper {
background: blue;
margin: 20px;
}
.flex-container {
padding: 0;
margin: 0;
list-style: none;
-ms-box-orient: horizontal;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -moz-flex;
display: -webkit-flex;
display: flex;
}
.flex-item {
background: tomato;
padding: 5px;
width: 50%;
height: 50px;
margin: 5px;
line-height: 50px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
}
// Abstraction for .row and .row-reverse styles based on nth-child
.wrapper :nth-child(odd) {
-webkit-flex-direction: row;
flex-direction: row;
}
.wrapper :nth-child(odd) :first-child {
flex-basis: 100px;
background: green;
}
.wrapper :nth-child(even) {
-webkit-flex-direction: row-reverse;
flex-direction: row-reverse;
}
.wrapper :nth-child(even) :first-child {
flex-basis: 100px;
background: gold;
}
How can I align 2 different Component side by side using flexbox ?
I have my 1st component "nav-menu" and the 2nd "homepage" I would like it to be side by side.
homepage.component.html
<app-nav-menu></app-nav-menu>
<div class="container">
<div>
<img src="https://colorlib.com/preview/theme/amado/img/product-img/pro-big-1.jpg">
</div>
</div>
I gave a width to my container
homepage.component.css
.container {
display: flex;
width: 50%;
}
div.container>div {
flex-grow: 1;
}
img {
width: 20%;
height: auto;
}
nav-menu.component.html
<h1>Furniture</h1>
<nav class="nav" role="navigation">
<ul clas="menu">
<li>Home</li>
<li>Shop</li>
<li>Product</li>
<li>Cart</li>
</ul>
</nav>
I gave a width to my nav
nav-menu.component.css
* {
box-sizing: border-box;
}
h1 {
display: flex;
justify-content: space-between;
margin-left: 30px;
margin-bottom: 100px;
}
nav {
width: 40%;
}
.nav ul {
margin: 0px;
padding: 0px;
background: white;
list-style: none;
}
.nav a {
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 0.5em;
text-decoration: none;
color: black;
font-size: 2em;
width: 10px;
}
.nav a:hover {
color: #FFA500;
transition: 0.1s;
}
whats the next step ?
thanks.
you have to wrap your both components in a flex
<div style="display: flex; flex-grow: grow">
<app-component-1></app-component-1>
<app-component-2></app-component-2>
</div>
I don't have problem keeping the left item having a fixed width using the flex-basis property. But I have a scenario wherein I don't want the left element to be fixed and keep the right element's width fixed instead. I tried putting flex-basis for the right element however, the problem is the flex items overflow its container.
Is there a way to achieve this? For example I have the layout below:
.flex-outer {
display: flex;
}
.dashboard {
flex-grow: 1;
}
.col {
margin-left: 25px;
flex-basis: 200px;
background: orange;
}
.flex-container {
display: flex;
justify-content: space-around;
}
.flex-item {
flex: 1 1 200px;
background: tomato;
padding: 5px;
height: 150px;
margin-top: 10px;
color: white;
font-weight: bold;
font-size: 3em;
display: flex;
justify-content: center;
align-items: center;
}
<div class="flex-outer">
<div class="dashboard">
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
</ul>
</div>
<div class="col">
</div>
</div>
Question
What I want to do is keep the right element (orange) 200px in a fixed width and just shrink the left flex-item (red) based on the available space. However, the problem is the right element is overflowing the container when the viewport is too narrow see image below.
As flex-shrink defaults to 1, it means .col is allowed to shrink below the given 200px.
Add flex-shrink: 0 to the .col rule and it won't.
Stack snippet
.flex-outer {
display: flex;
}
.dashboard {
flex-grow: 1;
}
.col {
margin-left: 25px;
flex-basis: 200px;
flex-shrink: 0; /* added */
background: orange;
}
.flex-container {
display: flex;
justify-content: space-around;
}
.flex-item {
flex: 1 1 200px;
background: tomato;
padding: 5px;
height: 150px;
margin-top: 10px;
color: white;
font-weight: bold;
font-size: 3em;
display: flex;
justify-content: center;
align-items: center;
}
<div class="flex-outer">
<div class="dashboard">
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
</ul>
</div>
<div class="col">
</div>
</div>
If you also want to completely avoid the orange box being pushed out of view, and as min-width defaults to auto, which means the dashboard and the flex-container won't get smaller than their content, you also need to set min-width: 0 to both of them so they will.
Stack snippet
.flex-outer {
display: flex;
}
.dashboard {
flex-grow: 1;
min-width: 0; /* added */
}
.col {
margin-left: 25px;
flex-basis: 200px;
flex-shrink: 0; /* added */
background: orange;
}
.flex-container {
display: flex;
justify-content: space-around;
}
.flex-item {
flex: 1 1 200px;
min-width: 0; /* added */
background: tomato;
padding: 5px;
height: 150px;
margin-top: 10px;
color: white;
font-weight: bold;
font-size: 3em;
display: flex;
justify-content: center;
align-items: center;
}
<div class="flex-outer">
<div class="dashboard">
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
</ul>
</div>
<div class="col">
</div>
</div>
A second option to handle the left items is of course to set flex-wrap: wrap to the flex-container
Stack snippet
.flex-outer {
display: flex;
}
.dashboard {
flex-grow: 1;
}
.col {
margin-left: 25px;
flex-basis: 200px;
flex-shrink: 0; /* added */
background: orange;
}
.flex-container {
display: flex;
flex-wrap: wrap; /* added */
justify-content: space-around;
}
.flex-item {
flex: 1 1 200px;
max-width: 200px; /* added, to keep them max 200px */
background: tomato;
padding: 5px;
height: 150px;
margin-top: 10px;
color: white;
font-weight: bold;
font-size: 3em;
display: flex;
justify-content: center;
align-items: center;
}
<div class="flex-outer">
<div class="dashboard">
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
</ul>
</div>
<div class="col">
</div>
</div>
What I want to do is keep the right element (orange) in a fixed width and just shrink the left flex-item (red) based on the available space.
You can use the css calc function to achieve this.
https://developer.mozilla.org/en/docs/Web/CSS/calc
Based on the classnames you used, you can do something like this:
.col {
width: 200px;
}
.flex-container {
width: calc(100% - 200px);
}
I created a fiddle https://jsfiddle.net/mh4moyzy/ and I'm not sure what I need to add so that when width of browser is greater than the width of mobile which is 400px, make all of those boxes stack in rows and as wide as the browser width. That means there will be 6 rows and 1 column. In mobile, there will be 3 rows and 2 columns.
.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 wrap;
justify-content: space-around;
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
height: 150px;
margin-top: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
</ul>
You should use media query for that. For making flex items take all width and have column direction add this code
#media (min-width: 400px) {
.flex-container {
flex-direction: column;
}
.flex-item {
width: auto;
}
}
Also if you want to always have 2 columns in your mobile you can add this styles to .flex-item:
width: calc(50% - 10px);
box-sizing: border-box;
So example will look like:
.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 wrap;
justify-content: space-around;
}
.flex-item {
background: tomato;
padding: 5px;
width: calc(50% - 10px); /* replacing fixed width with percentage */
height: 150px;
margin-top: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
box-sizing: border-box; /* Setting borders and paddings to be considered part of width */
}
#media (min-width: 400px) {
.flex-container {
flex-direction: column;
}
.flex-item {
width: auto;
}
}
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
</ul>
I have container with fixed height and display: flex. I want it's children to be laid in a column-first manner by setting -webkit-flex-flow: column wrap;.
http://jsfiddle.net/wNtqF/1/
Can anyone explain me how chrome calculates the resulting width of the container div (div with green border) and why is leaves so much free space on the right of each red item. What I want is to have the container to have width just to fit all children, without the additional empty space.
If it's not possible with pure css can you provide me an alternative to achive this?
I'm using Chrome v 29.0.1547.76
The code to reproduce it is:
<!DOCTYPE html>
<html>
<head>
<style>
.flex-container {
position: fixed;
height: 90%;
padding: 0;
margin: 0;
list-style: none;
border: 6px solid green;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: column wrap;
justify-content: flex-start
align-content: flex-start;
align-items: flex-start
}
/** Just to show the elements */
body {
margin: 0;
padding: 0;
}
.flex-item {
background: tomato;
padding: 5px;
width: 100px;
height: 100px;
margin-top: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
</style>
</head>
<body>
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
</ul>
</body>
Chrome automatically puts the space between the div and the border top, to fix this, you can just use:
margin-bottom: 100%;
Why this? margin-bottom: 100% reset the element and move the item up.
You've tried with:
body {
margin: 0;
padding: 0;
}
But this didn't work because body sposte the page html and not single element.
The complete code will are here:
.flex-container {
position: fixed;
height: 90%;
padding: 0;
margin: 0;
list-style: none;
border: 6px solid green;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: column wrap;
justify-content: flex-start
align-content: flex-start;
align-items: flex-start
}
/** Just to show the elements */
body {
margin: 0;
padding: 0;
}
.flex-item {
background: tomato;
padding: 5px;
width: 100px;
height: 100px;
margin-bottom: 100%;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
</ul>