Flexbox equal column height set dominant column height? - html

I have made this example:
.example {
max-width: 600px;
}
.flex-row {
display: flex;
flex-wrap: wrap;
}
.flex-row .col {
flex-grow: 1;
flex-basis: 0;
}
.flex-row .content {
flex: 0 0 60%;
padding: 15px;
background: #b7bdbb;
}
.image {
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.image img {
flex-shrink: 0;
min-width: 100%;
min-height: 100%;
}
<div class="example">
<div class="flex-row">
<div class="col image">
<img src="https://via.placeholder.com/500x265" alt="">
</div>
<div class="col content">
some content
</div>
</div>
</div>
I want my image on the left to be cropped but I want my content to dictate the overal height of the .example element.
Currently the image is dictating the overal height of the entire element. I want to image to be cropped to the size of the content that is in the right column. Is it do-able with my example?

If I understand you correctly you want your right column to set the overall height of #example
.example {
max-width: 600px;
}
.flex-row {
display: flex;
flex-wrap: wrap;
}
.flex-row .col {
flex-grow: 1;
flex-basis: 0;
}
.flex-row .content {
flex: 0 0 60%;
padding: 15px;
background: #b7bdbb;
}
.image {
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
position: relative;
}
.image img {
flex-shrink: 0;
min-width: 100%;
max-width: 100%;
position: absolute;
}
<div class="example">
<div class="flex-row">
<div class="col image">
<img src="https://via.placeholder.com/500x265" alt="">
</div>
<div class="col content">
some content
</div>
</div>
</div>

You can use position: relative on parent element and position: absolute on image and set height: 100%
.example {
max-width: 600px;
}
.flex-row {
display: flex;
flex-wrap: wrap;
}
.flex-row .content {
flex: 0 0 60%;
padding: 15px;
background: #b7bdbb;
}
.image {
flex: 1;
position: relative;
}
.image img {
height: 100%;
position: absolute;
vertical-align: top;
}
<div class="example">
<div class="flex-row">
<div class="col image"><img src="https://via.placeholder.com/500x265" alt=""></div>
<div class="col content">some content</div>
</div>
</div>

I want my image on the left to be cropped but I want my content to
dictate the overal height of the .example element.
When using an img, what first comes to mind is object-fit, though since it has not the best browser support, here is one that has, making use of background-image.
Generally, when using background-image, one set the image source in the external CSS, though sometimes one want to set it in the markup, like one does when using an img.
An often overlooked possibility when this is needed, is to simply use the style attribute, which is no more complicated than the src attribute on the img, where one can set the source in markup like this: style="background-image: url(...)"
I also used flex-basis: calc(60% - 30px). This overcome 2 bugs in IE, where one can't use calc in shorthand flex and the border-box issue to have padding inlcuded in the set width.
Stack snippet
.example {
max-width: 600px;
}
.flex-row {
display: flex;
flex-wrap: wrap;
}
.flex-row .image {
flex-grow: 1;
background-position: center;
background-size: cover;
}
.flex-row .content {
flex-basis: calc(60% - 30px);
padding: 15px;
background: #b7bdbb;
}
<div class="example">
<div class="flex-row">
<div class="col image" style="background-image: url(https://via.placeholder.com/500x265)">
</div>
<div class="col content">
some content
</div>
</div>
</div>
If you still need (or have to) use an img, here is one sample that work cross browsers.
Since several browsers, i.a. Safari (appears to be fixed from v. 11 though) and IE, have issues with Flexbox and absolute positioned flex items, I here make use of transform: translate to provide a solution to center the image.
Stack snippet
.example {
max-width: 600px;
}
.flex-row {
display: flex;
flex-wrap: wrap;
}
.flex-row .image {
flex-grow: 1;
position: relative;
overflow: hidden;
}
.flex-row .image img {
position: absolute;
left: 0;
top: 50%;
width: 100%;
transform: translateY(-50%);
}
.flex-row .content {
flex-basis: calc(60% - 30px);
padding: 15px;
background: #b7bdbb;
}
<div class="example">
<div class="flex-row">
<div class="col image">
<img src="https://via.placeholder.com/500x265)" alt="">
</div>
<div class="col content">
some content
</div>
</div>
</div>

You can achieve this using backgound-image property
.example {
max-width: 600px;
}
.flex-row {
display: flex;
flex-wrap: wrap;
}
.flex-row .col {
flex-grow: 1;
flex-basis: 0;
}
.flex-row .content {
flex: 0 0 60%;
padding: 15px;
background: #b7bdbb;
}
.image {
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
background-image:url('https://via.placeholder.com/500x265');
background-size:cover;
background-position:50% 50%;
}
.image img {
flex-shrink: 0;
min-width: 100%;
min-height: 100%;
}
<div class="example">
<div class="flex-row">
<div class="col image">
</div>
<div class="col content">
some content
</div>
</div>
</div>

Related

Place image next to div with flexbox

I have this image and this box I'm trying to put on the same line. The box is just going to be holding a header and some text, but I can't seem to get them on the same line. I'm using flexbox and I did some research into this, but can't quite work it out. Here's the code:
#container {
min-height: 95vh;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.box {
height: 400px;
width: 600px;
background-color: #f5f2ed;
text-align: justify;
padding: 20px;
}
img {
width: auto;
height: 400px;
border-radius: 16px;
}
<div id="container">
<div class="main">
<img src="/">
<div class="box">
<h2>hello</h2>
<p>paragraph here...</p>
</div>
</div>
</div>
I made two divs inside the container because the image is going to be outside the box with the text.
Maybe display: flex; in .main{} can fix the problem.
You should add display:flex property to main element and flex :1 property to both child elements of main element
#container {
min-height: 95vh;
}
.main {
display : flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.box {
height: 400px;
width: 50%;
flex : 1;
background-color: #f5f2ed;
text-align: justify;
padding: 20px;
}
img {
width: auto;
height: 400px;
flex : 1;
border-radius: 16px;
}
<div id="container">
<div class="main">
<div class="pic-div">
<img src="/">
</div>
<div class="box">
<h2>hello</h2>
<p>paragraph here...</p>
</div>
</div>
</div>

Height 100% inside flex item

I have a layout that is mainly divided into 3 parts and the middle one should take a full height. And it does.
However, I need an additional div which will play a role of the backdrop and here the problem comes. The child doesn't want to take 100% height.
Here .body is a div that is being stretched when there is not enough content and .bg-gray is the one I want to take its parent full height.
Is there a way achieve this without using relative + absolute positioning?
Also, I'm looking for the answer to my question: why is this happening that way.
html, body {
padding: 0;
margin: 0;
}
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: stretch;
}
.header {
height: 50px;
background-color: #e6e6e6;
}
.footer {
height: 50px;
background-color: #aaa444;
}
.body {
flex: 1;
}
.bg-gray {
background-color: #eee;
min-height: 100%;
flex: 1;
}
<div class="container">
<div class="header">
</div>
<div class="body">
<div class="bg-gray">
<div>
asdasd
</div>
</div>
</div>
<div class="footer">
</div>
</div>
Apply flexbox to the .body div.
.body {
flex: 1;
display: flex;
flex-direction: column;
}
html,
body {
padding: 0;
margin: 0;
}
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: stretch;
}
.header {
height: 50px;
background-color: #e6e6e6;
}
.footer {
height: 50px;
background-color: #aaa444;
}
.body {
flex: 1;
display: flex;
flex-direction: column;
}
.bg-gray {
background-color: darkgrey;
min-height: 100%;
flex: 1;
}
.bg-gray div {
background: lightblue;
}
<div class="container">
<div class="header">
</div>
<div class="body">
<div class="bg-gray">
<div>
asdasd
</div>
</div>
</div>
<div class="footer">
</div>
</div>

Have a div with the same height as a sibling image

I'm trying to do a responsive design of a panel consisting of an image and another container with its own internal elements, both side-by-side.
I have a parent div and inside an img and another div tags. Those two children tags have are floated block with a width in % and that works.
The problem is, when I shrink the page, the img shrinks to respect the % width rule and so does its height and it should stay that way, but the div on the side doesn't change its height to be the same as the sibling image.
I wrapped them in another div and put the internal div at height: 100% in hope that would do the trick but nothing.
I'd like to get the right div to change its height according to the left image.
.img-container {
display: block;
width: 59%;
float: left;
}
img {
width: 100%;
}
.product-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 41%;
float: left;
background-color: #e4d233;
}
.product-img {
width: 45%
}
<div class="imgProductContainer">
<div class="img-container">
<img src="http://pngimg.com/uploads/running_shoes/running_shoes_PNG5815.png"/>
</div>
<div class="product-container">
<img id="product2Img" class="product-img" src="http://pluspng.com/img-png/png-gym-shoes-shoe-away-hunger-is-a-partnering-program-where-footwear-is-turned-around-to-provide-an-eco-friendly-means-of-support-for-our-feeding-the-futures-programs-520.png">
<p><span id="product2Name"></span><br>
<span>2.00 €</span></p>
</div>
</div>
.imgProductContainer {
display: flex;
flex-direction: row;
/*
justify-content: center;
  align-items: center;
*/
}
.img-container {
width: 59%;
}
img {
width: 100%;
}
.product-container {
width: 41%;
background-color: #e4d233;
}
.product-img {
width: 45%
}
<div class="imgProductContainer">
<div class="img-container">
<img src="http://pngimg.com/uploads/running_shoes/running_shoes_PNG5815.png" />
</div>
<div class="product-container">
<img id="product2Img" class="product-img" src="http://pluspng.com/img-png/png-gym-shoes-shoe-away-hunger-is-a-partnering-program-where-footwear-is-turned-around-to-provide-an-eco-friendly-means-of-support-for-our-feeding-the-futures-programs-520.png">
<p><span id="product2Name"></span><br>
<span>2.00 €</span></p>
</div>
</div>
i guess thats how it should look like ?
i am not sure what .product-img class was for so i replaced productImg class with it.
i also removed all floats an just made the main container a flex box with its child aligned, you should look deeper into flexbox if you want something else here.
hope it helps
You can force equal height for the containers using CSS Grid:
.img-container {
display: flex;
width: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
}
img {
width: 100%;
}
.imgProductContainer {
display: grid;
grid-template-columns: 1fr 1fr;
}
.product-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
background-color: #e4d233;
}
.product-img {
width: 100%;
}
<div class="imgProductContainer">
<div class="img-container">
<img src="http://pngimg.com/uploads/running_shoes/running_shoes_PNG5815.png"/>
</div>
<div class="product-container">
<img id="product2Img" class="productImg" src="http://pluspng.com/img-png/png-gym-shoes-shoe-away-hunger-is-a-partnering-program-where-footwear-is-turned-around-to-provide-an-eco-friendly-means-of-support-for-our-feeding-the-futures-programs-520.png">
<p><span id="product2Name"></span><br>
<span>2.00 €</span></p>
</div>
</div>

chat web app: flex-boxes inside div position:fixed

I have a chat web app with a bottom bar consisting of: button, text entry, button:
<div id="bottom-bar">
<div class="button-left">
<img src="https://placeholdit.co//i/40x40">
</div>
<div class="textentry">
<input type="text" id="chatmsg" name="chatmsg">
</div>
<div class="button-right">
<img src="https://placeholdit.co//i/40x40">
</div>
</div>
#bottom-bar {
position: fixed;
bottom: 0px;
height: 40px;
width: 100%;
}
What I want to achieve: (1) place the left button to the left of the bottom-bar, (2) place the right button to the right of the bottom-bar and (3) have an input field that stretches in the middle using all the space that is available.
I tried:
#bottom-bar {
...the css above and additionally ...
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content:space-between;
align-items: center;
}
#chatmsg{
width: auto;
}
But this got me nowhere. Any help is much appreciated.
the textentry has to grow and take all the place left:
#bottom-bar {
position: fixed;
bottom: 0px;
height: 40px;
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content:space-between;
align-items: center;
}
.button-left,
.button-right {
width: 40px;
}
.textentry{
flex-grow: 1;
}
#chatmsg {
width: 100%;
}
check this: https://jsfiddle.net/43Lqzznt/3/
Use calc(100% - 80px); as the width for .textentry (i.e. full width minus the width of the two images) and make the input 100% wide inside of that. If you do just that, the input overflows its container to the right, so use padding on .textentry to compensate that and adjust the distance between the elements as desired, as shown in my snippet.
html,
body {
margin: 0;
}
#bottom-bar {
position: fixed;
bottom: 0px;
height: 40px;
width: 100%;
}
#bottom-bar {
display: flex;
justify-content: space-between;
align-items: center;
}
.textentry {
width: calc(100% - 80px);
padding: 0 10px 0 2px;
}
input#chatmsg {
width: 100%;
}
<div id="bottom-bar">
<div class="button-left">
<img src="https://placeholdit.co//i/40x40">
</div>
<div class="textentry"><input type="text" id="chatmsg" name="chatmsg"></div>
<div class="button-right">
<img src="https://placeholdit.co//i/40x40">
</div>
</div>
Using display:flex on the container and by adjusting the input div's flex:1 or setting it's width to 100% should do it. Check output in the console.
FLEX
The input box will stretch between the images as the container div shrinks or expands in size.
#bottom-bar {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content:space-between;
align-items: center;
}
#chatmsg{
width: 100%;
}
.textentry {
/* width: 100% */
flex: 1;
}
<div id="bottom-bar">
<div class="button-left">
<img src="https://placeholdit.co//i/40x40">
</div>
<div class="textentry">
<input type="text" id="chatmsg" name="chatmsg">
</div>
<div class="button-right">
<img src="https://placeholdit.co//i/40x40">
</div>
</div>

Incorrect image sizing in IE11 in flexbox

I am trying to position an image in a div. It should be centered. The div should have a minimum width and it should grow only if text below the image requires it.
The following code demonstrates what I want in Chrome:
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
background-color: aliceblue;
}
.loading-spinner-overlay-1 {
left: 0;
top: 0;
right: 0;
bottom: calc(100% - 300px);
position: absolute;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.loading-spinner-overlay-2 {
left: 0;
top: 300px;
right: 0;
bottom: calc(100% - 600px);
position: absolute;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.loading-spinner-background {
min-width: 100px;
min-height: 100px;
max-width: 50%;
background-color: white;
border-radius: 10px;
display: flex;
flex-direction: column;
z-index: 1;
padding: 20px;
}
.loading-spinner-container {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.loading-spinner-container > img {
margin: auto;
}
.loading-spinner-container > p {
text-align: center;
margin: 0;
}
<img src="http://placehold.it/40x40">
<div class="loading-spinner-overlay-1">
<div class="loading-spinner-background">
<div class="loading-spinner-container">
<img src="http://placehold.it/40x40">
</div>
</div>
</div>
<div class="loading-spinner-overlay-2">
<div class="loading-spinner-background">
<div class="loading-spinner-container">
<img src="http://placehold.it/40x40">
<p>
Some long text
</p>
</div>
</div>
</div>
However, in IE11, it looks like this:
Am I doing something wrong? Or is this a bug in IE11?
What can I do to fix this?
I have tried setting max-width: 100% and flex-shrink:0 on the img tag as some google results suggest, but this didn't help.
Updated
Adding align-items: flex-start to the loading-spinner-container fixes the issue, which kind of make sense, since align-items default is stretch and works cross axis (in this case horizontal) for flex column direction.
Updated, 2nd revision
Additionally, to fix the vertical centering, and since IE11 again has some issues when it comes to min-height, remove flex-direction: column from the loading-spinner-background and move min-height: 100px to loading-spinner-container.
Stack snippet
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
background-color: aliceblue;
}
.loading-spinner-overlay-1 {
left: 0;
top: 0;
right: 0;
bottom: calc(100% - 300px);
position: absolute;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.loading-spinner-overlay-2 {
left: 0;
top: 300px;
right: 0;
bottom: calc(100% - 600px);
position: absolute;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.loading-spinner-background {
min-width: 100px;
max-width: 50%;
background-color: white;
border-radius: 10px;
display: flex;
/* flex-direction: column; removed */
z-index: 1;
padding: 20px;
}
.loading-spinner-container {
min-height: 60px; /* added/value changed (moved from *-background class) */
display: flex;
flex-direction: column;
flex-grow: 1;
align-items: flex-start; /* added */
}
.loading-spinner-container > img {
margin: auto;
}
.loading-spinner-container > p {
text-align: center;
margin: 0;
}
<img src="http://placehold.it/40x40">
<div class="loading-spinner-overlay-1">
<div class="loading-spinner-background">
<div class="loading-spinner-container">
<img src="http://placehold.it/40x40">
</div>
</div>
</div>
<div class="loading-spinner-overlay-2">
<div class="loading-spinner-background">
<div class="loading-spinner-container">
<img src="http://placehold.it/40x40">
<p>
Some long text
</p>
</div>
</div>
</div>
Also align-items: center can be used, and if combined with justify-content: center, you can drop the margin: auto on the img.
Fiddle demo
Updated, 3rd revision, based on a comment
Longer text appears to not wrap on IE.
As shown in this post, IE need to have the width set explicit on the flex item, here p, and since also loading-spinner-container is a flex column item (for row item flex-grow is enough), it needs one too (or overflow: hidden).
Fiddle demo
Try this:
<div class="loading-spinner-overlay-2">
<div class="loading-spinner-background">
<div class="loading-spinner-container">
<div class="img-container"> <!-- added this -->
<img src="http://placehold.it/40x40">
<p>
Some long textwrwerwer
</p>
</div>
</div>
</div>
</div>
Then added new class:
.loading-spinner-container .img-container {
clear:both;
text-align:center;
}
Basically I added a wrapping div.
Hope it helps.