Nested flexbox image with same size container div - html

I am having issues with a nested flexbox container with an image inside of it. I need the image to maintain its 16x9 ratio always and would like the parent (or another div) to always be the exact size of the image, as I am using its coordinates to create a laser pointer feature and send it to other users.
I currently have the following Code:
#container {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
max-height: 100%;
height: 100%;
width: 100%;
padding: 0 2rem 2rem;
}
#container > div {
position: relative;
max-height: 100%;
height: 100%;
max-width: 100%;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
#container img {
height: auto;
max-height: 100%;
width: auto;
max-width: 100%;
}
<div id="container">
<div id="inner">
<img src="https://dummyimage.com/1600x900/000000/fff">
</div>
</div>
The #inner div and image match size when the #container is wider than the image:
However, when the image is full width, the #inner div is taller than the image:
Removing the #inner height works for the smaller widths, however the image then blows out of the container as the screen gets wider:
I have also tried some other solutions, such as adding object-fit: contain; to the image, and using a ratio-class with a padding-top of 56.25%, but can't seem to get any of these solutions to be fully responsive.
Any ideas are much appreciated!

If I get the idea correctly should be like this.
html, body {
height: 100%;
}
body {
margin: 0;
}
#container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
}
#inner {
display: flex;
align-items: center;
justify-content: center;
}
#inner img {
max-width: 100%;
max-height: 100%;
}
<div id="container">
<div id="inner">
<img src="https://dummyimage.com/1600x900/000000/fff">
</div>
</div>

Edit:
If you set your inner div as display inline block, it will always be the same size as the child image:
body{
margin: 0;
padding: 0;
box-sizing:border-box;
}
#container {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
width: 100%;
padding: 2rem;
box-sizing: border-box;
}
#container > div {
position: relative;
display: inline-block;
background: red;
font-size: 0;
box-sizing: border-box;
}
#container img {
height: auto;
width: 100%;
max-width: 100%;
display: block;
}
as in this example: https://jsfiddle.net/nzs21bem/
Is this what you are looking for?
You need to add some styles to your image so the ratio is preserved.
And display the image as a block element instead of the default inline style,
which has some padding to it.
.imgblock {
background: red;
margin: 30px;
}
.imgblock img {
width: 100%;
max-width: 100%;
}
.imgblock1 img {
display: block;
}
<div class="imgblock imgblock1">
<img src="https://dummyimage.com/1600x900/000000/fff">
</div>
That should make the parent the same size as the child image.
As you can see the difference in these 2 examples: https://jsfiddle.net/no1rqx6f/

Related

Fit and center div with containing image [CSS]

I made the following image to show my problem. Which CSS can I use to implement it?
For sure, i meant padding instead of margin of .page around the .image container...
Try something like this:
.page {
distplay: flex;
justify-content: center;
align-items: center;
}
.page .imagecontainer {
width: fit-content;
}
This could help you :)
.page {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.imagecontainer {
max-height: 100%;
max-width: 100%;
}

Css flex layout not aligning aligning items as desired

I am trying to position Author designation under Author name, i tried few thing since theme is using flex i find it hard to make it work.
This them is using flex all over the place and if change one thing it breaks other thing.
How can i place Author Designation under the Author Name with minimal css changes
https://codepen.io/KGuide/pen/OJJBzmp
.article-container .article-thumbnail-wrapper {
height: 480px;
height: auto;
}
.article-thumbnail-info {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
position: absolute;
width: 100%;
left: 0;
bottom: 20px;
padding: 0 15px;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-align-items: flex-start;
-ms-flex-align: start;
align-items: flex-start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.article-author {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
text-decoration: none !important;
}
.article-author figure {
margin: 0;
width: 50px;
height: 50px;
margin-right: 18px;
}
.article-author figure img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
Just wrapped two spans to div and aligned it to column with flex property:
https://codepen.io/Nevados/pen/mddzpYw
If the width of the image is static you can consider some margin trick. The 68px I am using is the width+margin for the image.
I removed some CSS to keep only the relevant one
.article-author {
display: flex;
flex-wrap: wrap; /* added */
/*align-items:center; removed */
text-decoration: none !important;
}
.article-author figure {
margin: 0;
width: 50px;
height: 50px;
margin-right: 18px;
}
.article-author figure img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
/* Added */
.blog-detail-author {
flex-basis: calc(100% - 68px);
margin-top: 5px;
}
.blog-detail-designation {
margin-left: 68px;
margin-top: -25px; /* This one is a bit hacky, you may need to change it based on the font or other CSS*/
}
<div class="article-thumbnail-wrapper blog-thumbnail-wrapper text-center">
<div class="article-author">
<figure class="article-author-avatar"><img alt="" src="http://themeflex.com/strucflex/en/structures/assets/img/avatar_2.jpg"></figure>
<span class="blog-detail-author">Author Name</span>
<span class="blog-detail-designation">Author Designation</span>
</div>
</div>
Try With this :
HTML
<div class="article-thumbnail-wrapper blog-thumbnail-wrapper text-center">
<div class="article-author">
<figure class="article-author-avatar"><img alt="" src="http://themeflex.com/strucflex/en/structures/assets/img/avatar_2.jpg"></figure>
<span>
<span class="blog-detail-author">Author Name</span>
<span class="blog-detail-designation">Author Designation</span>
</span>
</div>
</div>
CSS:
figure + span {
display:flex; flex-direction:column;
}

Flexbox footer not stacking under other divs

I created a layout using css and Flexbox, the issue is the footer div displays at the bottom of the page on load, but content shoots past it, so when you scroll the footer is just floating in the middle of the page. I'm not sure what to change.
I have changed the footer to be sticky, and bottom to be 0px. It kinda worked with adjusting the margin of the other divs, but its not very clean. I was hoping to keep using the flexbox attributes and just have them stack, but that doesn't seem to work? I've also adjusted the min-max heights of the other divs, but as soon as the window shrinks past the min height the footer just floats over the rest of the content.
Link to code JSFiddle
.footer{
height:40px;
display:flex;
align-items:center;
justify-content:center;
width:100%;
background-color:purple;
}
I would suspect that the footer would obey the stacking order and just display under the rest of the content, like the main body does under the header.
It's the height set on your '.content' class. Change height: calc(100vh - 100px) to min-height: calc(100vh - 100px)
Unless you want the footer and header always visible, then you can just add overflow: auto to make the content scroll
Remove height: calc(100vh - 100px); from .content class
body,
html {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
.bodywrap {
display: flex;
flex-wrap: wrap;
align-content: space-between;
background-color: black;
}
.header {
display: flex;
justify-content: space-between;
width: 100%;
height: 60px;
background-color: brown;
}
.hleft {
display: flex;
align-items: center;
justify-content: center;
width: 250px;
background-color: lightgreen;
}
.hmid {
display: flex;
align-items: center;
justify-content: center;
flex-grow:1;
font-size: calc(1.5vw);
background-color: orange;
}
.hright {
display: flex;
align-items: center;
justify-content: center;
width: 400px;
background-color: pink;
}
.content {
display: flex;
justify-content: space-between;
background-color: darkblue;
}
.lmenu {
display: flex;
width: 250px;
flex-wrap: wrap;
align-content: space-between;
height: 100%;
min-height: 600px;
background-color: lightgrey;
overflow: hidden;
}
.ltop {
display: flex;
align-items: center;
justify-content: center;
height: 150px;
width: 100%;
background-color: blue;
}
.lmid {
height: 50px;
width: 100%;
background-color: green;
}
.lbot {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
width: 100%;
background-color: yellow;
}
.rmaincont {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
width: calc(100vw - 250px);
background-color: grey;
}
.note {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: lightblue;
height: 50px;
}
.main {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
height: calc(100vh - 50px);
min-height: 550px;
width: 100%;
padding-left: 20px;
background-color: red;
}
.footer {
height: 40px;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
background-color: purple;
}
<!DOCTYPE html>
<html>
<head>
<title>Mid-Valley Intranet</title>
<link rel="stylesheet" type="text/css" href="css/cstyle.css">
</head>
<body>
<div class="bodywrap">
<header class="header">
<div class="hleft">Left</div>
<div class="hmid">Mid</div>
<div class="hright">Right</div>
</header>
<div class="content">
<div class="lmenu">
<div class="ltop">
Top
</div>
<div class="lmid">
Mid
</div>
<div class="lbot">
Bot
</div>
</div>
<div class="rmaincont">
<div class="note">
Notice
</div>
<div class="main">
Main Content
</div>
</div>
</div>
<footer class="footer">
Footer Text
</footer>
</div>
</body>
</html>
There are a few things did to do to make this work:
Originally the scrolling was happening on the body. I added overflow: hidden on the body and overflow-y: auto to the div with the "bodywrap" class.
I added the position sticky and bottom 0, but with vendor prefixes:
bottom: 0;
position: -webkit-sticky;
position: -moz-sticky;
position: -ms-sticky;
position: -o-sticky;
I also made the div with class "bodywrap" have a height equal to 100vh minus the height of the footer (so that the scrolling content doesn't get cutoff at the bottom). You may want to set a sass variable or something for this 40px height.
height: calc(100vh - 40px);
Here's a demo of the new version:
jsfiddle.net/webwhizjim/6f84b7su/3/

Image inside flex parent with max-height and max-width and object-fit contain

Image stretches if I don't use object-fit contains. Stretches in width, losing aspect ratio.
object-fit contain fixes that.
The problem is, the element itself is not contained, just the visible image. Which means if I make the image clickable, the whole element area (even outside the image) is clickable.
https://jsfiddle.net/nyysyngp/10/ (or see code below)
I just want the visible image to be clickable. This seems to work on Firefox, but not Chrome.
body, html
{
margin: 0;
padding: 0;
background-color: red;
display: flex;
height: 100%;
width: 100%;
}
#media
{
display: flex;
background-color: #262423;
justify-content: center;
align-items: center;
flex-direction: column;
flex-grow: 1;
}
#media_split
{
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
align-items: center;
}
#media_image_container
{
height: 50%;
width: 100%;
flex-grow: 1;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: green;
}
#media_image
{
object-fit: contain;
max-height: calc(100% - 4em);
max-width: calc(100% - 4.7em);
min-height: 100px;
min-width: 100px;
cursor: pointer;
}
#media_tv
{
height: 50%;
width: 100%;
flex-grow: 1;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
background-color:blue;
}
<div id='media'>
<div id='media_split'>
<div id='media_image_container'>
<img id='media_image' src='https://i.imgur.com/F26h0tq.jpg'>
</div>
<div id='media_tv'></div>
</div>
</div>
Well some months later I found a solution. Just by adding "position: absolute" to #media_image the problem went away, which in my case didn't break anything else.
In #media_image_container remove display: flex; and add text-align: center;
It will fix the issue.

Why does margin: auto only work horizontally and not vertically?

I have seen that while developing websites, vertically centering a container (of fixed height) inside a container of random height always comes as a nightmare for the web developer (at least, me) while when it comes to horizontal centering a container (of fixed width) inside a container of random width, the margin:0px auto; tends to serve an easy way out in the standard model.
When things can be as simple as that why doesn't CSS work out with the margin:auto 0px; when it comes to centering a container of fixed height inside a container of random height? Is there any specific reason to do so?
It's really less of a nightmare than you think, just don't use margins. vertical-align is really what you should rely on for fluid-height vertical centering. I threw together a quick demo to demonstrate my point:
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
text-align: center;
}
span {
height: 100%;
vertical-align: middle;
display: inline-block;
}
#any-height {
background: #000;
text-align: left;
width: 200px;
height: 200px;
vertical-align: middle;
display: inline-block;
}
<span></span>
<div id="any-height"></div>
See: http://jsfiddle.net/Wexcode/jLXMS/
The right answer for your question is that margin: auto 0 doesn't work the same way that margin: 0 auto works because width: auto doesn't work the same way height: auto does.
Vertical auto margin works for absolutely positioned elements with a known height.
.parent {
position: relative;
}
.child {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
width: 150px;
height: 150px;
margin: auto;
}
Use flexbox parent
One of advantages of using margin: auto compared to justify-content: center / align-items: center is ability to scroll child item that is overflowing parent
html, body {
height: 100%;
margin: 0;
}
.parent {
display: flex;
width: 100%;
height: 100%;
}
.inner {
width: 100px;
height: 100px;
background-color: green;
margin: auto;
}
<div class="parent">
<div class="inner">
</div>
</div>
CSS
.aligncenter{
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-align: center;
-moz-box-align: center;
flex-align: center;
-webkit-box-pack: center;
-moz-box-pack: center;
flex-pack: center;
}
HTML
<div class="aligncenter">
---your content appear at the middle of the parent div---
</div>
.aligncenter {
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-align: center;
-moz-box-align: center;
flex-align: center;
-webkit-box-pack: center;
-moz-box-pack: center;
flex-pack: center;
}
<div class="aligncenter">
---your content appear at the middle of the parent div---
</div>
Note
This CSS class work with almost all browsers