Flexbox: Why flex-grow doesn't work with fixed width sibling? - css

LIVE DEMO
Consider the following HTML and CSS:
<div class="wrapper">
<div class="first">The CSS3 Flexible Box, or flexbox, is a layout mode providing for the arrangement .</div>
<div class="second"></div>
</div>
<div class="wrapper">
<div class="first"></div>
<div class="second"></div>
</div>
.wrapper {
display: flex;
border: 1px solid black;
width: 300px;
height: 100px;
margin-top: 30px;
}
.first {
flex-grow: 1;
background-color: #aaa;
}
.second {
width: 80px;
background-color: #ddd;
}
and the following result:
Why the first wrapper doesn't respect .second's width: 80px?
How could I fix that using flexbox?
PLAYGROUND HERE

You need to use flex: 1; instead of flex-grow: 1;
.first {
flex: 1;
background-color: #aaa;
}
Demo
Also, I would like to point out that flexbox support isn't good as far as IE is concerned, so if anyones interested in a similar layout with more compatible option, than
<div class="wrapper">
<div class="second"></div>
<div class="first"></div>
</div>
.wrapper {
border: 1px solid black;
width: 300px;
height: 100px;
margin-top: 30px;
}
.wrapper .first {
background: red;
height: 100%;
margin-right: 80px;
}
.wrapper .second {
height: 100%;
width: 80px;
float: right;
background: blue;
}
Demo (Note that I swapped the order of the div in the DOM)

Related

CSS problem with divs and inline components

Imagine a code like this:
.div {
width: 100%;
height: 100px;
background-color: green;
}
.div1 {
width: 100px;
height: 100px;
background-color: red;
}
.div2 {
width: 100px;
height: 100px;
background-color: blue;
}
.main {
background-color: yellow;
}
<div class="main">
<div>
<div class="div"></div>
<div class="div1"></div>
</div>
<div class="div2"></div>
</div>
It will render something like this:
I want that the blue div comes up and stay on the right of the red div. Imagine that I canĀ“t change the divs from where they are, so I need to do it in css. How can I do it?
Without changing the markup, if you set float: left to the red <div> then you could put the blue <div> to its right side
.div {
width: 100%;
height: 100px;
background-color: green;
}
.div1 {
width: 100px;
height: 100px;
background-color: red;
float: left;
}
.div2 {
width: 100px;
height: 100px;
background-color: blue;
display: inline-block;
vertical-align: top;
}
.main {
background-color: yellow;
}
<div class="main">
<div>
<div class="div"></div>
<div class="div1"></div>
</div>
<div class="div2"></div>
</div>
The previous solution which uses float on the red div works well, but here is another possible solution:
Apply position: relative; to the blue div (to be able to move it in relation to its default position) and add top: -100px; left: 100px; to move it up next to the red div:
.div {
width: 100%;
height: 100px;
background-color: green;
}
.div1 {
width: 100px;
height: 100px;
background-color: red;
}
.div2 {
width: 100px;
height: 100px;
background-color: blue;
position: relative;
top: -100px;
left: 100px;
}
.main {
background-color: yellow;
}
<div class="main">
<div>
<div class="div"></div>
<div class="div1"></div>
</div>
<div class="div2"></div>
</div>
This can also be done with the grid CSS. Here I used a named template box and then in the "chatty verbose" CSS I put the positional related for each "block". I added classes to the CSS just for clarity but you could update to your classes.
I added some color and things just for clarity and visual references but kept the "position relate" in separate CSS chunks.
.main {
font-size: 2rem;
display: grid;
grid-template: "box";
background-color: yellow;
}
.main *,
.main::before {
grid-area: box;
}
.green-block {
place-self: start;
}
.red-block {
width: 50%;
place-self: end start;
}
.blue-block {
width: 50%;
place-self: end end;
}
.green-block {
height: 3rem;
background-color: green;
}
.red-block {
height: 3rem;
background-color: red;
}
.blue-block {
background-color: blue;
}
.blue-block,
.green-block,
.red-block {
/* color for clarity and just to super center the text in the blocks */
display: grid;
color: cyan;
font-family: sans-serif;
text-transform: uppercase;
place-items: center;
}
<div class="main">
<div>
<div class="div green-block">green</div>
<div class="div1 red-block">red</div>
</div>
<div class="div2 blue-block">blue</div>
</div>

Stop flexbox item "flex:1" from taking more space caused from the width of the children [duplicate]

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 2 years ago.
I have the following html/css. Which renders like this:
.parent {
display: flex;
width: 200px;
height: 100px;
background-color: red;
}
.one {
flex: 1;
background-color: green;
}
.two {
flex: 1;
/* width: 100px; <-- this is what I'd like to achieve */
background-color: yellow;
}
.inner {
width: 150px; /* <-- this is bigger than width of .parent */
height: 50px;
background-color: blue;
}
<div class="parent">
<div class="one"></div>
<div class="two">
<div class="inner"></div>
</div>
</div>
As you can see the div with .inner is 150px causing its parent div, with flex: 1, to take more space.
What I'd like to achieve is this:
I know the existence and tried to use, flex-grow and flex-shrink. I couldn't make it work.
The question: is there a way to make it work using only flexbox?
Easily managed with position: relative one two and position:absolute on inner
.parent {
display: flex;
width: 200px;
height: 100px;
background-color: red;
}
.one {
flex: 1;
background-color: green;
}
.two {
position: relative;
flex: 1;
/* width: 100px; <-- this is what I'd like to achieve */
background-color: yellow;
}
.inner {
position:absolute;
width: 150px; /* <-- this is bigger than width of .parent */
height: 50px;
background-color: blue;
}
<div class="parent">
<div class="one"></div>
<div class="two">
<div class="inner"></div>
</div>
</div>
Only using max-width:50% on class two
DEMO 2
.parent {
display: flex;
width: 200px;
height: 100px;
background-color: red;
}
.one {
flex: 1;
background-color: green;
}
.two {
flex: 1;
max-width: 50%;
/* width: 100px; <-- this is what I'd like to achieve */
background-color: yellow;
}
.inner {
width: 150px; /* <-- this is bigger than width of .parent */
height: 50px;
background-color: blue;
}
<div class="parent">
<div class="one"></div>
<div class="two">
<div class="inner"></div>
</div>
</div>

why is padding not being applied internally when using border-box

I've got a simple question which hopefully has a simple answer. It seems basic but I just can't get my head around it.
So, I've got four boxes arranged in a container:
div {
box-sizing: border-box;
padding: 0;
margin: 0;
}
.wrapper {
box-sizing: content-box;
height: 600px;
width: 600px;
margin: 100px auto;
border: 2px solid gray;
}
.box-container {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.box {
width: 300px;
height: 300px;
padding: 0px;
}
.c {
background-color: cyan;
}
.y {
background-color: yellow;
}
.m {
background-color: magenta;
}
.k {
background-color: black;
}
<div class="wrapper">
<div class="box-container">
<div class="box c"></div>
<div class="box y"></div>
<div class="box m"></div>
<div class="box k"></div>
</div>
</div>
I've applied box-sizing: border-box; to the divs, but for some reason padding is having no effect at all. If I use margin then it makes the divs too big for the wrapper, and they move position.
What am I missing here?
Thanks in advance
Jamie
Your HTML & CSS is correct. If you need padding on all the .c .m .y .k boxes, then use
.box {
width: 300px;
height: 300px;
padding: 10px;
border: 10px solid #000; //border also works
}

css 100% width don't work when zooming

I have here some code
.container{
height: 200px;
width: 100%;
background-color: black;
}
.container_1{
margin-bottom: 50px;
height: 200px;
width: 20000px;
background-color: black;
}
<div class="container_1">
</div>
<div class="container">
</div>
If you scroll to right side, the .container stopped. But I gave him a with of 100%, why it won't work?
It is 100% of its parent, which is the body. The body didn't get an explicit width, so it's just as wide as the client size of the window. The other div is forced to be wider (20000px), so it extends outside of the bounds of the body.
In the snippet below, I've added a border to the body, so you can see how the second div snugly fits into that boundary.
.container {
height: 200px;
width: 100%;
background-color: black;
opacity: 0.5;
}
.container_1 {
opacity: 0.5;
margin-bottom: 50px;
height: 200px;
width: 20000px;
background-color: black;
}
body {
border: 3px solid red;
}
<div class="container_1">
</div>
<div class="container">
</div>
Because its 100% of the view port
Try this,
.main_container{
float:left;
}
.container{
height: 200px;
width: 100%;
background-color: black;
}
.container_1{
margin-bottom: 50px;
height: 200px;
width: 20000px;
background-color: black;
}
<div class="main_container">
<div class="container_1">
</div>
<div class="container">
</div>
</div>

Trying to get a div positioned over two others either relatively or absolute

HTML:
<div id="outer1">
<div class="bg">
<div class="top"></div>
<div class="base"></div>
</div>
<div class="content"></div>
</div>
<div id="outer2">
<div id="bg">
<div class="top"></div>
<div class="base"></div>
</div>
<div class="content"></div>
</div>
CSS2:
div { width: 100%; }
#outer1, #outer2 {position: relative;}
#outer1 .top { height: 200px; background-color: blue; }
#outer1 .base { height: 200px; background-color: yellow; }
#outer2 .top { height: 200px; background-color: green; }
#outer2 .base { height: 200px; background-color: yellow; }
.content {
width: 160px; margin: 0 auto;
position: relative; bottom: 250px; height: 300px; background-color: white; border: 1px solid black;}
This is the fiddle
The white, black-bordered div (.content) is supposed to sit on the split-coloured background (.bg) (as it is).
Using relative positioning - but the space i've told it to move up by (250px), is still been taken by it's parent (#outer1). (there's a gap between to the two 'outer' divs - they should be touching)
I tried absolute positioning but because the content div is taller than the relative content, the height is not honoured. And becuase it's dynamic content I cannot give it a fixed height (although i did for illustration)
One option is javascript, another is using a background-repeater for the top half.
Can it be achieved with pure CSS2?
Edit: Complete rewrite...
Here is the new fiddle: http://jsfiddle.net/FSXj8/14/
Okay so I took the liberty to start from scratch. Here is the html
<div id="outer1" class="container">
<div class="content">
<div class="innerContent">hello world</div>
</div>
<div class="top"></div>
<div class="base"></div>
</div>
<div id="outer2" class="container">
<div class="content">
<div class="innerContent">hello world</div>
</div>
<div class="top"></div>
<div class="base"></div>
</div>
And here is the CSS
div {
width: 100%;
}
.container {
height: 400px;
display: table;
position: relative;
}
.top, .base {
position: absolute;
left: 0;
height: 50%;
z-index: 0;
}
.top {
top: 0;
}
.base {
bottom: 0;
}
#outer1 .top {
background-color: blue;
}
#outer1 .base {
background-color: yellow;
}
#outer2 .top {
height: 50%;
background-color: green;
}
#outer2 .base {
height: 50%;
background-color: yellow;
}
.innerContent {
min-height: 100px;
border: 1px solid black;
background-color: white;
width: 100px;
}
.content {
display: table-cell;
position: relative;
vertical-align: middle;
z-index: 1;
background-color: transparent;
height: 100%;
}
Not sure if this is what you want, you said something about not using absolute:
.content {
width: 100px; margin 0 auto;
position: absolute; margin-top:-250px; height: 100px; background-color: white; border: 1px solid black;}
http://jsfiddle.net/FSXj8/7/

Resources