Flex column, column exceeding container width - html

I can't get the flex: column working so that child elements don't exeed the parent. The left block is an image, it has to be 100% of containers height:
.container {
width: 500px;
height: 300px;
border: solid blue 1px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.tall {
height: 100%;
width: 300px;
background: yellow;
}
.row {
margin: 10px 0;
background: red;
min-height: 10px;
}
<div class="container">
<div class="tall"></div>
<div class="row">This is a text that should be multiline, with automatic width depending on the left block width.</div>
<div class="row"></div>
<div class="row"></div>
</div>
The right rows no matter what I try are always exceeding the container, their width is always container width, not the remaining space widht. How can I achieve it?

I would change the direction of your flex so it is row and remove the flex wrap, then I would wrap your rows in a div with flex-grow:1 and remove the height from tall:
.container {
width: 500px;
height: 300px;
border: solid blue 1px;
display: flex;
flex-direction: row;
}
.tall {
width: 300px;
background: yellow;
}
.row-holder {
flex-grow:1;
}
.row {
margin: 10px 0;
background: red;
min-height: 10px;
}
<div class="container">
<div class="tall"></div>
<div class="row-holder">
<div class="row">This is a text that should be multiline, with automatic width depending on the left block width.</div>
<div class="row"></div>
<div class="row"></div>
</div>
</div>

Related

How to make a div occupy 100% within another div in Vue

I want to make two div inside other div. But the second(green) div is passing the size of the main(black). I tried to set the height to 100%, but something happens that is going beyond the size of the main box, does anyone have any solutions?
.block {
width: 300px;
height: 200px;
background: black;
}
.box1 {
width: 200px;
height: 50px;
background: red;
vertical-align: top;
margin: auto;
}
.box2 {
width: 200px;
height: 100%;
background: green;
margin: auto
}
<div class="block">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
If you set child's height to 100% then the height of the parent will be inherited. If you are looking for an option where the 2nd box (green) fill the remaining space leftover by 1st box(red)
.block {
width: 300px;
height: 200px;
background: black;
display: flex;
flex-direction: column;
align-items: center;
}
.box1 {
width: 200px;
height: 50px;
background: red;
vertical-align: top;
}
.box2 {
flex: 1;
width: 200px;
background: green;
}
<div class="block">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
I am using Flex and there is no need to use overflow: hidden
You should add the overflow: hidden; to the main black box, just like the below snippet. This will make the overflow clipped.
.block {
width: 300px;
height: 200px;
background: black;
overflow: hidden;
}
.box1 {
width: 200px;
height: 50px;
background: red;
margin: auto;
}
.box2 {
width: 200px;
height: 100%;
background: green;
margin: auto;
}
<div class="block">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
But if you don't want to get rid of the remaining piece of the second box, you can do it with flexbox also. This will not trim the green box but instead, it will resize it to make sure the green box will remain in the parent black box.
.block {
width: 300px;
height: 200px;
background: black;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.box1 {
width: 200px;
height: 50px;
background: red;
}
.box2 {
width: 200px;
height: 100%;
background: green;
}
<div class="block">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
NOTE: In the flexbox version, you also won't need to use margin: auto; in the child boxes, because in the flexbox column direction align-items: center; will take care of child positions with the available attributes it gave to us.

Use `height:100%` when parents div have only min-height

Use height:100% when parents div have only min-height.
.line {
background-color: gray;
width: 1px;
height: 100%;
margin-left: 10px;
margin-right: auto;
}
.main {
min-height:200px;
}
<div class="col-6">
<div class=line>
</div>
<div class="col-6 main">
set by min-width
</div>
Using height:100% doesn't work when parents doesn't have height.
In this case, heights of main div changed depending on the amount of contents.
Because it has only min-height;
So, height:100% of line class doesn't work.
Is there a way to solve??
Consider using flex to do this.
As I understand, you want your line to fill your parent div while main class takes up at least 200px?
.parent {
display: flex;
flex-direction: column;
height: 600px;
}
.fill {
background-color: grey;
flex: 1;
}
.line {
flex-grow: 0;
min-height: 200px;
background-color: red;
}
.content-with-more-than-200px-height {
height: 220px;
}
<div class="parent">
<div class="fill">
</div>
<div class="line">
<div class="content-with-more-than-200px-height">
contents
</div>
</div>
</div>

Scroll-x as overflow not working - shows scrollbar for y instead

I'm trying to understand why I cannot scroll horizontally to see the other pink thumbs. I added an overflow of scroll-x to the thumbs container and thought it would allow me to scroll horizontally to see the other thumbs; instead, it only scrolls vertically.
Can someone explain why it doesn't scroll horizontally? thanks a million
#content-wrap {
background: lightgreen;
width: 300px;
height: 300px;
}
#main-image {
background: cyan;
width: 300px;
height: 250px;
float: left;
}
#thumbs-wrap {
background: orange;
width: 300px;
height: 50px;
float: left;
overflow-x: scroll;
}
.thumb {
background: pink;
box-sizing: border-box;
width: 75px;
height: 50px;
border: 2px solid grey;
float: left;
}
<div id="content-wrap">
<div id="main-image"></div>
<div id="thumbs-wrap">
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
</div>
</div>
It's because your #thumbs-wrap has fixed width, and it's not enough to keep all child elements in one row or add horizontal scrollbar. As an easy solution, you can wrap all child elements inside another one div and give extra-width to it. Here is an example:
#content-wrap {
background: lightgreen;
width: 300px;
height: 300px;
}
#main-image {
background: cyan;
width: 300px;
height: 250px;
float: left;
}
#thumbs-wrap {
background: orange;
width: 300px;
height: 50px;
float: left;
overflow-x: scroll;
}
#thumbs-inner-wrap {
width: 1000px;
}
.thumb {
background: pink;
box-sizing: border-box;
width: 75px;
height: 50px;
border: 2px solid grey;
float: left;
}
<div id="content-wrap">
<div id="main-image"></div>
<div id="thumbs-wrap">
<div id="thumbs-inner-wrap">
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
</div>
</div>
</div>
HTML elements will usually wrap to new lines when there is no more horizontal space. That's why you get a vertical scrollbar even if you set overflow-x: auto. You can use CSS flexbox to override this behavior without adding any more elements. Add the following to your CSS:
#thumbs-wrap {
display: flex;
flex-wrap: nowrap;
}
.thumb {
flex: 0 0 auto;
}
How does this work?
flex-wrap:nowrap makes sure we force the child elements to stay on one line, and not wrap to new lines.
Now usually this might make the flex items shrink or grow to fit the horizontal space of their parent element. We can control this by controlling their sizes.
The flex property with three values is shorthand for flex: flex-grow flex-shrink flex-basis.
With flex-grow and flex-shrink set to 0, the flex items are not allowed to either grow/expand or shrink to fit the space of the container.
flex-basis:auto makes sure the flex items are sized exactly the way we have already sized them in our CSS.
Together these rulesets forces the flex items (.thumb) to be aligned horizontally, not wrap to a second line and to remain their original size. This will force a horizontal scrollbar to appear on the #thumbs-wrap element.
You can see how this works out together with your code:
#content-wrap {
background: lightgreen;
width: 300px;
height: 300px;
}
#main-image {
background: cyan;
width: 300px;
height: 250px;
float: left;
}
#thumbs-wrap {
background: orange;
width: 300px;
height: 50px;
float: left;
overflow-x: scroll;
display: flex;
flex-wrap: nowrap;
}
.thumb {
flex: 0 0 auto;
background: pink;
box-sizing: border-box;
width: 75px;
height: 50px;
border: 2px solid grey;
float: left;
}
<div id="content-wrap">
<div id="main-image"></div>
<div id="thumbs-wrap">
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
</div>
</div>

Flex 2 columns where one is fixed width and the other is width 100%

I am trying to divide my page into 2 columns. I want content on the left with a padding on it together with a border. On the right I want my sidebar, which has a fixed width.
https://jsfiddle.net/mortenmoulder/04fkrkpp/
#container {
display: flex;
flex-direction: row;
justify-content: space-between;
height: 100%;
}
I have tried doing that, but I'm not sure if I should use space-between or something else. I have basically achieved what I want, but the padding should be equal on all the sides. How do I achieve that?
You can use flex-grow:1; instead of width:100%;, and you need to change of few other things as well
Use border directly on #left-container and add margin instead of padding, this will make the space equal to all sides.
See updated fiddle
body,
html {
height: 100%;
margin: 0;
}
#container {
display: flex;
flex-direction: row;
height: 100%;
}
#left-container {
flex-grow: 1;
border: 20px solid black;
margin: 50px;
}
#left {
height: 100%;
}
#right {
width: 300px;
border-left: 1px solid black;
}
<div id="container">
<div id="left-container">
<div id="left">
<p>
Some content here
</p>
<p>
Some content here
</p>
<p>
Some content here
</p>
</div>
</div>
<div id="right">
<p>
Right sidebar
</p>
</div>
</div>
check below code I just added flex: 1 and remove some unnecessary code from your demo
body,
html {
height: 100%;
margin: 0;
}
#container {
display: flex;
/*flex-direction: row;
justify-content: space-between;*/
height: 100%;
}
#left-container {
padding: 50px;
width: 100%;
flex: 1;
}
#left {
border: 20px solid black;
height: 100%;
/*width: 100%;*/
}
#right {
width: 300px;
border-left: 1px solid black;
}
<div id="container">
<div id="left-container">
<div id="left">
<p>
Some content here
</p>
<p>
Some content here
</p>
<p>
Some content here
</p>
</div>
</div>
<div id="right">
<p>
Right sidebar
</p>
</div>
</div>
https://jsfiddle.net/04fkrkpp/3/

flexbox grid under centered flex item

I would like an intro section on the left side of a .container and a side bar on the right.
On the left side underneath the .intro section I want there to be four divs equally spaced like a grid.
I'm having problems with getting the "grid set up". I think part of the problem is that the parent has some flexbox attribute effecting the children.
Requirement : The intro section should be centered in the .left-side and the "grid" should not be centered the boxes should take up as much space as necessary to fit 2 on a row with margins in between. The .intro should be 80 percent of the width of the leftside.
I don't want to do any major changes to the structure this is just a small sample of how my project is set up.
.container{
width: 80%;
margin: 0 auto;
display: flex;
}
.left-side{
flex:8;
display: flex;
justify-content:center;
flex-wrap: wrap;
}
.side-bar{
flex: 2;
height: 100vh;
background: powderblue;
}
.intro{
flex:3;
width:80%;
height: 300px;
background: skyblue;
}
.box{
background: red;
width: 45%;
height: 100px;
flex:4;
border:1px solid orange;
}
<div class="container">
<div class="left-side">
<div class="intro">
intro
</div>
<div class="recent">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
</div>
<div class="side-bar">
sidebar
</div>
Flex items can also be flex containers. This enables you to nest multiple containers, with flex-direction: row or column, in a larger container.
For your layout, you can build a column consisting of two flex items. The first item (.intro) has 80% width and can be centered horizontally. The second item (.recent) can be a flex container with four items arranged in a 2x2 grid.
.container {
width: 80%;
margin: 0 auto;
display: flex;
justify-content: center;
height: 100vh;
}
.left-side {
flex: 4;
display: flex;
flex-direction: column;
}
.side-bar {
flex: 1;
background: powderblue;
}
.intro {
flex: 3;
height: 300px;
width: 80%;
margin: 0 auto;
background: skyblue;
}
.recent {
display: flex;
flex-wrap: wrap;
background-image: url("http://i.imgur.com/60PVLis.png");
background-size: contain;
}
.box {
margin: 5px;
flex-basis: calc(50% - 10px);
height: 100px;
box-sizing: border-box;
background: red;
}
body { margin: 0; }
<div class="container">
<div class="left-side">
<div class="intro">intro</div>
<div class="recent">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
</div>
<div class="side-bar">
sidebar
</div>
</div>