Fit content in to flex direction column [duplicate] - html

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 2 years ago.
Im trying to fit content into a div with a flex.
Works perfectly into a flex-direction:row; (Standar) but isenĀ“t work into a flex-direction:column;
In "column" just overflow my div, do not resize the elements inside.
How can i do to resize elemetns to fit into a div with out know cuantity of elemnts?
https://codepen.io/nandordena/pen/jObjJNw
HTML
<body>
<div class="column">
<div>
<video src="https://www.w3schools.com/tags/movie.ogg">
</div>
<div>
<video src="https://www.w3schools.com/tags/movie.ogg">
</div>
<div>
<video src="https://www.w3schools.com/tags/movie.ogg">
</div>
</div>
<div class="row">
<div>
<video src="https://www.w3schools.com/tags/movie.ogg">
</div>
<div>
<video src="https://www.w3schools.com/tags/movie.ogg">
</div>
<div>
<video src="https://www.w3schools.com/tags/movie.ogg">
</div>
</div>
</body>
CSS
div{
border:solid 1px #f00;
margin:1px;
flex:1;
}
body{
border:solid 1px #00f;
pading:1px;
display:flex;
height: 500px;
width: 500px;
}
.row{
display:flex;
flex-direction:row;
}
.column{
display: flex;
flex-direction:column;
}
video {
max-height:100%;
max-width:100%;
}

Probably the easiest (not sure if a correct way), to let column grow and don't let it shrink. You can achieve this by adding flex: 1 0 auto; to your wrapper (.row > div)

Grid can do the trick
.grd {
display: grid;
grid-template-columns: auto;
grid-template-rows: 50px;
}
.item1 {
background-color: blue;
width: 120px;
grid-row: 1;
}
.item2 {
background-color: pink;
width: 1fr;
grid-row: 1;
}
.item3 {
background-color: red;
width: 20px;
grid-row: 1;
}
.item4 {
background-color: darkblue;
width: 1fr;
grid-row: 1;
}
<div class="grd">
<div class="item1">One</div>
<div class="item2">Two</div>
<div class="item3">Three</div>
<div class="item4">Four</div>
</div>

Related

Flex positioning of sidebar when in particular order

I have a simple 2-column layout with 3 sections. Depending on a media query, I want to change the order of them - for this I am using flex order.
This works fine, except I get my narrow sidebar section starting at the end of the first section, or similar to this. Is there a way I can get them to position more like jigsaw pieces?
Fiddle example of issue:
https://jsfiddle.net/an7m3yvs/
HTML:
<div class="page-wrapper">
<div class="container">
<div class="box1">
BOX 1
</div>
<div class="box2">
BOX 2
</div>
<div class="box3">
BOX 3 Sidebar
</div>
</div>
</div>
CSS:
.page-wrapper{
width:100%;
max-width:500px;
margin:0 auto;
}
.container{
display:flex;
flex-wrap:wrap;
}
.box1{
display:inline-block;
background:red;
width:70%;
height:400px;
order:1;
}
.box2{
display:inline-block;
background:green;
width:70%;
height:150px;
order:2;
}
.box3{
display:inline-block;
background:grey;
width:30%;
height:600px;
order:3;
}
How I want it:
(I know this can be done simpler but the idea is so I can change the order with a media query, as in mobile I want a single column and them in a different order.)
GRID ATTEMPT: https://jsfiddle.net/w489b2fj/
The 3rd element is not positioned according to the first element but to its predecessor. The sidebar will occupy the remaining space after the 2nd element and not the 1st.
To achieve the desired result, I think it is better to manage 2 flexbox containers. The first includes box1 and box2. The second includes box container and the sidebar.
Edit HTML:
<div class="page-wrapper">
<div class="container">
<div class="content-wrapper">
<div class="box1">
BOX 1
</div>
<div class="box2">
BOX 2
</div>
</div>
<div class="box3">
BOX 3 Sidebar
</div>
</div>
</div>
And edit the CSS:
.container, .content-wrapper{
display:flex;
flex-wrap:wrap;
}
.content-wrapper {
width: 70%;
}
.box1, .box2 {
width: 100%;
}
EDIT:
Ok, with this new information I have another solution:
.container {
position: relative;
}
.box3 {
position: absolute;
top: 0;
right: 0;
}
You can achieve that by adding flex-direction: column; to the container. But in this case (in order to wrap the items) you also need to set a fixed height, in your case height: 550px;.
And actually, you don't need the order settings for the flex items in this simple case...
.page-wrapper {
width: 100%;
max-width: 500px;
margin: 0 auto;
}
.container {
display: flex;
flex-wrap: wrap;
flex-direction: column;
height: 550px;
}
.box1 {
display: inline-block;
background: red;
width: 70%;
height: 400px;
order: 1;
}
.box2 {
display: inline-block;
background: green;
width: 70%;
height: 150px;
order: 2;
}
.box3 {
display: inline-block;
background: grey;
width: 30%;
height: 600px;
order: 3;
}
<div class="page-wrapper">
<div class="container">
<div class="box1">
BOX 1
</div>
<div class="box2">
BOX 2
</div>
<div class="box3">
BOX 3 Sidebar
</div>
</div>
</div>
You wanted an answer using CSS Grid, where box3 places inbetween box1 and box2 in mobile viewports. Here you are:
.container{
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas:
"box1"
"box3"
"box2"
}
#media (min-width:768px){
.container{
display:grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas:
"box1 box3"
"box2 box3"
}
}
.box1{
grid-area: box1;
background-color: #f00;
}
.box2{
grid-area: box2;
background-color: #0f0;
}
.box3{
grid-area: box3;
background-color: #00f;
}
<div class="page-wrapper">
<div class="container">
<div class="box1">
BOX 1
</div>
<div class="box2">
BOX 2
</div>
<div class="box3">
BOX 3 Sidebar
</div>
</div>
</div>
Try using position property and place the boxes relative to page wrapper.
if you can change HTML ( and always make good structure ) try this:
do the flex on c1 and c2 elements and you simply remove all inline-block instructions
<div class="page-wrapper">
<div class="container">
<div class=c1>
<div class="box1">
BOX 1
</div>
<div class="box2">
BOX 2
</div>
</div>
<div class=c2>
<div class="box3">
BOX 3 Sidebar
</div>
</div>
</div>
And css:
.page-wrapper{
width:100%;
max-width:500px;
margin:0 auto;
}
.container{
display:flex;
}
.box1{
background:red;
height:200px;
order:2;
}
.box2{
background:green;
height:150px;
order:1;
}
.box3{
background:grey;
width:100%;
height:400px;
}
.c2{
width:30%;
flex-basis:1;
}
.c1{
display:flex;
flex-direction:column;
width:70%;
flex-basis:1;
}

Grid align horizontal center is not works

.parent{
border:1px solid red;
display:grid;
grid-template-columns: repeat(12, 1fr);
}
.child{
background:green;
align-self:center;
}
<div class="parent">
<div class="child" style="justify-self: center;">
I am child
</div>
</div>
I am looking a solution to let child should align itself to center. so i can create a class name for left, right, and center will use across.
What's happening here for you is automatic grid placement. Technically speaking the item is aligned to the center inside the first column you created. The problem is that it ends up all the way on the left because that's where your first column actually is.
There's a few ways you can approach this if you want to continue using CSS Grid for this layout concept. But the problem with a 12 col grid is that there won't be a "center" without some offsetting or transforms.
I recommend you use the following if you really only need one row with 3 possible placements. It's a 13 col grid with a defined height of a single row, this ensures if the items are being shuffled out of order (if left is second like my example) that they won't jump to a second implied row.
.parent{
border:1px solid red;
display:grid;
grid-template-columns: repeat(13, 1fr);
grid-template-rows: 60px;
}
.center{
background:green;
grid-column: 7/8;
grid-row: 1/2;
}
.left {
background: red;
grid-column: 1/2;
grid-row: 1/2;
}
.right {
background: blue;
grid-column: 13/14;
grid-row: 1/2;
}
<div class="parent">
<div class="center">
I am child
</div>
<div class="left">
Me too
</div>
<div class="right">
Also me
</div>
</div>
Edit: You can also use flexbox and drop some of the complexity and get better responsiveness by using the order property and justifying the content as space-between.
.parent {
border: 1px solid red;
display: flex;
justify-content: space-between;
}
.center {
background: green;
order: 2
}
.left {
background: red;
order: 1
}
.right {
background: blue;
order: 3
}
<div class="parent">
<div class="center">
I am child
</div>
<div class="left">
Me too
</div>
<div class="right">
Also me
</div>
</div>
Here is an optimized version with flexible values that can work with any number of columns.
I will consider CSS variables to easily adjust the template and the center element. For the left and right we only need 1 and -1
.parent{
--n:6;
display:grid;
grid-template-columns: repeat(calc(2*var(--n)), 1fr);
grid-auto-flow:dense;
margin:5px;
outline:1px solid;
}
.left{
grid-column-start:1;
}
.right{
grid-column-end:-1;
text-align:right;
}
.center {
grid-column:calc(var(--n))/span 2;
text-align:center;
}
.parent > * {
border:1px solid red;
}
<div class="parent">
<div class="left">
left
</div>
<div class="right">
right
</div>
<div class="center">
center
</div>
</div>
<div class="parent" style="--n:3">
<div class="left">
left
</div>
<div class="right">
right
</div>
<div class="center">
center
</div>
</div>
<div class="parent" style="--n:10">
<div class="left">
left
</div>
<div class="right">
right
</div>
<div class="center">
center
</div>
</div>
.parent {
border: 1px solid red;
display: grid;
grid-template-columns: repeat(1, 1fr);
}

CSS - Positioning of multiple adjacent divs to have one stack on top of each other between 2 divs [duplicate]

This question already has answers here:
Make a div span two rows in a grid
(2 answers)
Closed 2 years ago.
I'm facing an issue where I need to make several adjacent div to position a certain way:
Their html layout positions are right next to each other:
<div class="parent">
<div class="div1">....</div>
<div class="div2">....</div>
<div class="div3">....</div>
<div class="div4">....</div>
</div>
I've tried with flex boxes and floating out Div1 and Div4 out but it's not working. I also need Div1 and Div4's height to all be vertically aligned to its correct dynamic height depending on the contents of Div2 and Div3.
CSS grid may help you solve it easily.
.parent {
display: grid;
grid-gap: 10px;
grid-template-columns: [col1-start] 100px [col2-start] 100px [col3-start] 100px [col3-end];
grid-template-rows: [row1-start] auto [row2-start] auto [row2-end];
}
.div1, .div2, .div3, .div4 {
background-color: #444;
color: #fff;
padding: 20px;
}
.div1 {
grid-column: col1-start;
grid-row: row1-start / row2-end ;
}
.div2 {
grid-column: col2-start ;
grid-row: row1-start;
}
.div3 {
grid-column: col2-start;
grid-row: row2-start ;
}
.div4 {
grid-column: col3-start ;
grid-row: row1-start / row2-end ;
}
<div class="parent">
<div class="div1">....</div>
<div class="div2">....</div>
<div class="div3">....</div>
<div class="div4">....</div>
</div>
Some more examples could be found HERE.
I would do it this way:
*{
margin: 0;
border: 0;
padding: 0;
box-sizing: border-box;
}
.parent{
display: flex;
padding: 15px;
}
.a, .b{
background: #ddd;
margin: 10px;
flex-basis: 20%;
}
.container{
width: 60%;
}
.container div{
background: #ddd;
margin: 10px;
}
<div class="parent">
<div class="a">div1</div>
<div class="container">
<div>div</div>
<div>div</div>
</div>
<div class="b">div2</div>
</div>

FlexBox Filling blank spaces

So in the image below, I created a flexbox for a sidebar, a main area, and then a small area up to the right as a login area.
The first sidebar on the left has a fixed height of 600px, the mainarea in the middle has a height of 100vh, and the right sidebar has a fixed height of 200px.
My questions is if it is possible to fill in the blank space on the right, underneath the green with the main area content with flexbox. Is this possible, or is flexbox not the way to go with this layout?
I essentially want the content my main area red content to flow beneath the green area.
.main {
display: flex;
flex-wrap: wrap;
border: 0px solid black;
height: 100vh;
}
.sidebar {
background: #F1F1F9;
flex: 1;
height: 600px;
}
.mainArea {
flex: 3;
background: red;
}
.rightSidebarSmall {
flex: 1;
background: green;
height: 200px;
}
<link href="//fonts.googleapis.com/css?family=Raleway:300,400,600,700" rel="stylesheet">
<div class="main">
<div class="sidebar">
<div class="logo">
<img src="img/sound-wave-icon.png" height="100px" width="140px">
</div>
<div class="selectorBar">
</div>
<div class="menu">
<ul class="menuOptions">
<li>Recent Files</li>
<li>Projects</li>
<li>Teams</li>
<li>Archives</li>
</ul>
</div>
<div class="addButton">
plus icon button
</div>
<div class="progressBar">
uploading 5 files <br> progressBar <br> 9.8mbps 36 secs remaining
</div>
</div>
<div class="mainArea"></div>
<div class="rightSidebarSmall"></div>
</div>
Using CSS Grid is the easiest way to go about this, since the layout you are going for is very unorthodox. With that said, I was able to get a layout that I think fits your description that I put in a Pen.
https://codepen.io/anon/pen/bLjNRO
The gist of it adds:
.main {
display: grid;
grid-template-columns: repeat(5, 1fr);
}
.mainArea {
grid-column: 1 / 6;
grid-row: 1;
}
.rightSidebarSmall {
grid-column: 5 / 6;
grid-row: 1;
}
I think it is better if you can make the right sidebar to position absolute. with this your main (red arean) will be cover full with and green area will be overlap on the red area
.main {
display: flex;
flex-wrap: wrap;
border: 0px solid black;
height: 100vh;
position:relative;
}
.sidebar {
background: #F1F1F9;
flex: 1;
height: 600px;
}
.mainArea {
flex: 3;
background: red;
}
.rightSidebarSmall {
position:absolute;
right:0;
top:0;
z-index: 10;
min-width:100px;
height:200px;
background:green;
}
<div class="main">
<div class="sidebar"></div>
<div class="mainArea"></div>
<div class="rightSidebarSmall"></div>
</div>
Hope it will help you :)
Sure, just use float: right Just make sure the floating div is before the rest of your text.
.main {
width: 50vw;
height: 50vh;
position: relative;
}
.inner {
background-color: red;
float: left;
width: 100%;
height: 100%;
word-break: break-all;
}
.other {
background-color: green;
float: right;
max-width: 150px;
}
<div class="main">
<div class="inner">
<div class="other">
another text asdfsdf asdf asdf
</div>
<div>
The quick brown fox The quick brown fox The quick brown fox
</div>
</div>
</div>

A flexbox grid of two flex items next to one [duplicate]

This question already has answers here:
Is it possible for flex items to align tightly to the items above them?
(5 answers)
Make a div span two rows in a grid
(2 answers)
Closed 5 years ago.
I am trying to have one div on the left and two on the right. The bottomright should always be below the topRight div. The topRight is the only div with a variable height.
I am currently trying to achieve this using flexbox als you can see in my code below.
I would like to have some directions.
.wrapper {
display: flex;
height: 100px;
}
.left {
background-color: green
}
.topRight {
background-color: yellow
}
.bottomright {
background-color: red
}
<div class="wrapper">
<div class="left">Left</div>
<div class="topRight">TopRight</div>
<div class="bottomright">Bottom</div>
</div
With a fixed height on the container, as you have in your code, you can use flex-direction: column and flex-wrap: wrap. The fixed height serves as a break point, telling flex items where to wrap.
.wrapper {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 100px;
}
.left {
flex: 0 0 100%; /* consumes full height of first column; forces siblings to wrap */
background-color: lightgreen
}
/* variable height div */
.topRight {
background-color: yellow
}
.bottomright {
flex: 1; /* consumes remaining space in column */
background-color: red
}
<div class="wrapper">
<div class="left">Left</div>
<div class="topRight">TopRight<br>variable height</div>
<div class="bottomright">Bottom</div>
</div>
On html put a div with a class called right wrapping both topRight and bottomRight and use this css on css:
.wrapper {
display: flex;
height: 100px;
}
.right {
display: flex-flow;
}
.left {
background-color: green
}
.topRight {
background-color: yellow;
height: 50px;
}
.bottomright {
background-color: red;
height: 50px;
}
I hope that helps you :)
For infos
display:grid is made for this .... very soon available for most browsers and yet for a few
A tutorial among others : https://css-tricks.com/snippets/css/complete-guide-grid/
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* any height s */
background-color: green;
}
.leftspan {
grid-row: span 2;/* if 2 rows avalaible */
}
.topRight {
background-color: yellow;
grid-column: 2 /-1
}
.bottomright {
background-color: red;
grid-column: 2 /-1
}
.bottomfull {
background-color: red;
grid-column: 1 /-1
}
<div class="wrapper">
<div class="leftspan">Left spanning 2 rows</div>
<div class="topRight">Top <br/>Right</div>
<div class="bottomright">Bottom <br/>Right</div>
</div>
<p> or did you mean ?
<div class="wrapper">
<div class="left">Left</div>
<div class="topRight">Top Right</div>
<div class="bottomfull">Bottom <br/>Right</div>
</div>
render if your browsers understand grid: