dynamical width of div stacks - html

I have a stack of div boxes as follows:
My goal is: Box B and C should be of the same width, and box A should be the width of B and C. The content of each box should be shown without line break. They should be arranged as in the picture. The content of box A, B and C is created dynamically.
I almost achieved this (see code at bottom) by putting these 3 boxes in an display:inline-block and setting width:50% for box B and C. This works good in some cases, but when the content of box B is too large, I get this result:
I understand the outcome, since the total width is determined by box A and box B has width: 50%. However, I would like that box B gets stretched so that no line break is needed, like this:
How can I achieve this?
This is the code that produces the image (see this jsFiddle):
<style>
.container{
display: inline-block;
text-align:center;
padding: 5px;
border:dashed red;
}
.head{
border:solid;
background-color: yellow;
padding: 30px;
}
.item{
width: 50%;
display: inline-block;
border:solid;
box-sizing: border-box;
padding: 5px;
}
.red{
background-color: red;
}
.green{
background-color: green;
}
}
</style>
<div class="container">
<div class="head">
A
</div>
<div>
<div class="item red">
B
</div><!--
--><div class="item green">
C
</div>
</div>
</div>

A minor change on structure and flexbox can do that.
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.container {
display: inline-flex;
text-align: center;
padding: 5px;
border: dashed red;
flex-wrap: wrap
}
.head {
border: solid;
background-color: yellow;
flex: 0 0 100%;
padding: 30px;
}
.item {
width: 50%;
display: inline-block;
border: solid;
box-sizing: border-box;
padding: 5px;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
<div class="container">
<div class="head">
Very very long text
</div>
<div class="item red">
Also very very long text
</div>
<div class="item green">
C
</div>
</div>
Or...if you want the bottom divs wrapped...still flexbox
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.container {
display: inline-flex;
text-align: center;
padding: 5px;
border: dashed red;
flex-wrap: wrap
}
.head {
border: solid;
background-color: yellow;
flex: 0 0 100%;
padding: 30px;
}
.wrap {
flex: 0 0 100%;
display: flex;
}
.item {
width: 50%;
display: inline-block;
border: solid;
box-sizing: border-box;
padding: 5px;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
}
<div class="container">
<div class="head">
Very very long text
</div>
<div class="wrap">
<div class="item red">
Also very very long text
</div>
<div class="item green">
C
</div>
</div>
</div>

Related

Position button inside a div to the bottom right

I would like the button to be positioned at the bottom right of the red colored div. I used padding-bottom and margin-bottom properties but that does not seem to work. Could anyone please help?
.container {
display: flex;
flex-direction: column;
width: 300px;
height: 200px;
border: 1px solid blue;
padding: 8px;
}
.box {
width: 300px;
height: 150px;
border: 1px solid red;
}
.button {
float: right;
}
<div class="container">
<div class="box">
</div>
<div>
<button class="button">Click</button>
</div>
</div>
.button {
float: right;
position:relative;
transform:translate(-5px,-25px); //x and y controls
}
I have just answered the same thing to other question. ... Use position:relative. I see the point why people refrain from using it. But really ain't no shame. Especially when there isn't a parent-child relation between the elements.
.container {
display: flex;
flex-direction: column;
width: 300px;
height: 200px;
border: 1px solid blue;
padding: 8px;
}
.box {
width: 300px;
height: 150px;
border: 1px solid red;
}
.button {
float: right;
position:relative;
top: -22px;
}
<div class="container">
<div class="box">
</div>
<div>
<button class="button">Click</button>
</div>
</div>
An alternative to the other answers using display: grid instead. This is easier for the browser than using position absolute or float!!
/* ignore */ body { margin: 0 } * { box-sizing: border-box } /* ignore */
.container {
display: grid;
width: 50vw;
height: 100vh;
border: 1px solid blue;
padding: 8px;
}
.box, .button { grid-area: 1/1/-1/-1 }
.box { border: 1px solid red }
.button { margin: auto 0 0 auto }
<div class="container">
<div class="box">
</div>
<div class="button">
<button>Click</button>
</div>
</div>

Scrollable element inside a container filling remaining space

I have a container flexbox element filling the remaining space inside a container. Inside that, I want an element that can fill the parent and scroll on overflow. Problem is, is always just overflows the container, and I can't set height: 100%, since that won't take into account a header with a dynamic height.
Please see this code snippet for a clearer example. I want to scroll on the purple div, but the red div keeps overflowing the blue div, which it shouldn't. I would highly prefer to not change the HTML, only the CSS.
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.wrapper {
height: 100%;
padding: 10px;
box-sizing: border-box;
background: blue;
width: 300px;
display: flex;
flex-direction: column;
}
.header {
padding: 10px;
background: green;
}
.content {
padding: 10px;
background: red;
flex: 1;
box-sizing: border-box;
}
.boxes {
padding: 10px;
background: purple;
height: 100%;
overflow-y: auto;
box-sizing: border-box;
}
.box {
height: 200px;
border: 1px solid black;
box-sizing: border-box;
background: orange;
}
<div class="wrapper">
<div class="header">
This is the header.
It has multiple lines.
</div>
<div class="content">
<div class="boxes">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</div>
Not sure if this is what you are looking for. I have just added overflow: scroll to content class and it seems to work.
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.wrapper {
height: 100%;
padding: 10px;
box-sizing: border-box;
background: blue;
width: 300px;
display: flex;
flex-direction: column;
}
.header {
padding: 10px;
background: green;
}
.content {
padding: 10px;
background: red;
flex: 1;
box-sizing: border-box;
overflow-y: scroll;
}
.boxes {
padding: 10px;
background: purple;
height: 100%;
overflow-y: auto;
box-sizing: border-box;
}
.box {
height: 200px;
border: 1px solid black;
box-sizing: border-box;
background: orange;
}
<div class="wrapper">
<div class="header">
This is the header. It has multiple lines.
</div>
<div class="content">
<div class="boxes">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</div>
Using overflow-y: hidden; on the .content hides everything that would overflow it's parent container
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.wrapper {
height: 100%;
padding: 10px;
box-sizing: border-box;
background: blue;
width: 300px;
display: flex;
flex-direction: column;
}
.header {
padding: 10px;
background: green;
}
.content {
padding: 10px;
background: red;
flex: 1;
box-sizing: border-box;
overflow: hidden;
}
.boxes {
padding: 10px;
background: purple;
height: 100%;
overflow-y: auto;
box-sizing: border-box;
}
.box {
height: 200px;
border: 1px solid black;
box-sizing: border-box;
background: orange;
}
<div class="wrapper">
<div class="header">
This is the header.
It has multiple lines.
</div>
<div class="content">
<div class="boxes">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</div>
Here, if you check, I have given max-height: calc(100% - 38px); to the .content to have a max-height. Giving flex: 1 will provide it a min-height only, it will grow more if the there is content and there is space in its wrapper. So by providing a max-height, we can avoid this issue
* {
box-sizing: border-box;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.wrapper {
height: 100%;
padding: 10px;
background: blue;
width: 300px;
display: flex;
flex-direction: column;
}
.header {
padding: 10px;
background: green;
}
.content {
padding: 10px;
background: red;
flex: 1;
max-height: calc(100% - 38px);
}
.boxes {
padding: 10px;
background: purple;
overflow-y: auto;
max-height: 100%;
}
.box {
height: 200px;
border: 1px solid black;
background: orange;
}
<div class="wrapper">
<div class="header">
This is the header.
It has multiple lines.
</div>
<div class="content">
<div class="boxes">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</div>

How to make the child fit 100% of parent height with fixed view?

I have a div that has a fixed height of 20cm. Now, the inner page needs to have padding and position absolute needs to respect that padding.
How can I make the red box fill always what's left? The position absolute item needs to be always at the bottom no matter what.
It needs to have one class, and not 10classes with 10different heights like 58%, 45% etc...
If you check the codepen: https://codepen.io/Aurelian/pen/MqxvgW
Here's the HTML:
<div class="page">
<div class="image"></div>
<div class="page-inner-default">
<p>hello</p>
<span class="pos-bot">Hi</span>
</div>
</div>
<div class="page">
<div class="image"></div>
<h1>Heading</h1>
<div class="page-inner-default">
<p>hello</p>
<span class="pos-bot">Hi</span>
</div>
</div>
Here's the CSS:
*, *:before, *:after {
box-sizing: border-box;
}
body {
background: grey;
box-sizing: border-box;
}
.image {
height: 250px;
border: 1px solid green;
background: green;;
}
.pos-bot {
position: absolute;
bottom: 0;
}
.page {
height: 20cm;
background-color: white;
width: 16cm;
margin: 50px auto;
display: inline-block;
vertical-align: top;
position: relative;
}
.page-inner-default {
position: relative;
padding: 50px;
height: 100%;
border: 1px solid red;
}
.image {
}
Give the .page{overflow:hidden} and remove the position relative from the .page-inner-default so the .pos-bot will be positioned to the closest relative and in this case it is the .page div
*, *:before, *:after {
box-sizing: border-box;
}
body {
background: grey;
box-sizing: border-box;
}
.image {
height: 250px;
border: 1px solid green;
background: green;;
}
.pos-bot {
position: absolute;
bottom: 0;
}
.page {
overflow: hidden;
height: 20cm;
background-color: white;
width: 16cm;
margin: 50px auto;
display: inline-block;
vertical-align: top;
position: relative;
}
.page-inner-default {
padding: 50px;
min-height: 100%;
border: 1px solid red;
}
<div class="page">
<div class="image"></div>
<div class="page-inner-default">
<p>hello</p>
<span class="pos-bot">Hi</span>
</div>
</div>
<div class="page">
<div class="image"></div>
<h1>Heading</h1>
<div class="page-inner-default">
<p>hello</p>
<span class="pos-bot">Hi</span>
</div>
</div>

Position element at the bottom with prior element filling up height

First div should fill up remaining height that's left while second div should be positioned at the bottom with it's initial height.
DEMO:
.container {
width: 240px;
height: 400px;
background: #E0E0E0;
display: flex;
flex-direction: column;
}
.first {
border :1px solid black;
padding: 1em;
box-sizing: border-box;
}
.second {
border: 1px solid blue;
padding: 1em;
box-sizing: border-box;
}
<div class="container">
<div class="first">
I SHOULD FILL WHATS REMAINING AFTER SECOND ONE
</div>
<div class="second">
<div>
I SHOULD BE AT THE BOTTOM FILLING ONLY MY OWN HEIGHT
</div>
</div>
The answer to this would vary from markup to markup, but in your case you can just add this to your first element:
height: 100%;
This works because of your flex display property of the container. A different property on the container would likely require another solution.
Demo
Full code
.container {
width: 240px;
height: 400px;
background: #E0E0E0;
display: flex;
flex-direction: column;
}
.first {
height: 100%;
border :1px solid black;
padding: 1em;
box-sizing: border-box;
}
.second {
border: 1px solid blue;
padding: 1em;
box-sizing: border-box;
}
<div class="container">
<div class="first">
I SHOULD FILL WHATS REMAINING AFTER SECOND ONE
</div>
<div class="second">
<div>
I SHOULD BE AT THE BOTTOM FILLING ONLY MY OWN HEIGHT
</div>
</div>
You need to make height auto to container class so depend on length of string your height is increase.
<style>
.container {
width: 240px;
height: auto;
background: #E0E0E0;
display: flex;
flex-direction: column;
}
.first {
border :1px solid black;
padding: 1em;
box-sizing: border-box;
}
.second {
border: 1px solid blue;
padding: 1em;
box-sizing: border-box;
}
</style>
<div class="container">
<div class="first">
I SHOULD FILL WHATS REMAINING AFTER SECOND ONE
</div>
<div class="second">
<div>
I SHOULD BE AT THE BOTTOM FILLING ONLY MY OWN HEIGHT
</div>
</div>

Two boxes don't place themselves correctly, but the other does

Trying to make a website built up by boxes of different sizes.
Been mixing a lot with it but can't get this last thing to work.
EDIT: So, as you can se in the JSFiddle, the two last boxes are starting on a new row. I want them to be placed between the two mediumNews DIV and under the lineNews DIV. But they just start a new row. Here is a simple Paint note to show how I want it.
Image of how I want it to be.
JSFiddle Here!
Here is also the code used in the JSFiddle:
HTML
<div id="wrapNews">
<div class="bigNews">
L
</div>
<div class="mediumNews">
M
</div>
<div class="lineNews">
L
</div>
<div class="smallNews">
S
</div>
<div class="smallNews">
S
</div>
<div class="smallNews">
S
</div>
<div class="smallNews">
S
</div>
<div class="mediumNews">
THEY SHOULD BE TO THE RIGHT OF THIS ONE...
</div>
<div class="lineNews">
AND UNDER THIS ONE...
</div>
<div class="mediumNews">
AND TO THE LEFT OF THIS ONE
</div>
<div class="smallNews">
THIS BOX IS WRONG
</div>
<div class="smallNews">
AND THIS ONE TO
</div>
</div>
CSS
* {
padding: 0;
margin: 0;
outline: 1px solid red;
}
body {
background-image: url('bg3.jpg');
font-family: Helvetica;
}
#header {
width: 900px;
margin: 0 auto;
}
#wrapNews {
width: 920px;
margin: 0 auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.lineWrap {
overflow: hidden;
}
.smallNews {
display: inline-block;
width: 210px;
height: 200px;
border: 1px solid grey;
float: left;
box-sizing: border-box;
margin: 10px;
}
.lineNews {
display: inline-block;
width: 440px;
height: 200px;
border: 1px solid grey;
float: left;
box-sizing: border-box;
margin: 10px;
}
.mediumNews {
display: inline-block;
width: 210px;
height: 420px;
border: 1px solid grey;
float: left;
box-sizing: border-box;
margin: 10px;
}
.bigNews {
display: inline-block;
width: 900px;
height: 400px;
border: 1px solid grey;
float: left;
box-sizing: border-box;
margin:10px;
}
Just float:right this div :
<div class="mediumNews" style="float:right">
AND TO THE LEFT OF THIS ONE
</div>
Example