Image in Lightbox hangs outside of container - html

I build a responsive lightbox with flexbox-styling and the image in this lightbox doesnt fit in the container. (Its working fine if there is enough vertical space).
Here is a image to visualize the problem:
Thats the HTML code:
<div id="dialog-container">
<div id="dialog">
<div id="dialog-content">
<div class="image-wrapper">
<img src="https://spotwild.org/css/images/dist/header/header-07-1600.jpg">
</div>
<div class="thumbs">
Here are the thumbs
</div>
</div>
</div>
</div>
CSS:
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
width: 100%;
}
#dialog-container {
position: absolute;
width: 100%;
height: 100%;
background: black;
display: flex;
justify-content: center;
align-items: center;
}
#dialog {
max-width: 80%;
max-height: 80%;
background: white;
padding: 50px;
box-sizing: border-box;
position: relative;
}
#dialog-content {
display: flex;
flex: 1 1 100%;
flex-direction: column;
box-sizing: border-box;
height: 100%;
max-height: 100%;
}
.image-wrapper {
display: flex;
flex: 1 1 auto;
justify-content: center;
align-items: center;
min-width: 0;
min-height: 0;
}
img {
min-width: 0;
min-height: 0;
max-height: 100%;
max-width: 100%;
display: flex;
flex: 0 0 auto;
}
.thumbs {
background: #eee;
padding: 20px;
line-height: 25px;
box-sizing: border-box;
}
And here is the corresponding jsfiddle:
https://jsfiddle.net/ppkzt7m6/1/
Does somebody has a solution and an explanation why this happens?

The important part is to define the height on all the parent containers for the <img> element to make the percentage heights to work properly.
And use object-fit: cover; on the <img> element. Note, the current IE11 and Edge don't support it, works fine on all other modern browsers though, see the support tables.
jsFiddle
You can also do it without flexbox, the key is to set the image caption to absolute position
jsFiddle
I suggest to use background image if you do need to support IE, example:
jsFiddle
<div class="image-wrapper" style="background: url('https://spotwild.org/css/images/dist/header/header-07-1600.jpg') center / cover;">

add height in #dialog
#dialog {
background: white none repeat scroll 0 0;
box-sizing: border-box;
height: 100%;
max-height: 80%;
max-width: 80%;
padding: 50px;
position: relative;
}

USE THIS.
img {
display: block;
height: 100%;
max-height: 100%;
max-width: 100%;
min-height: 0;
min-width: 0;
width: 100%;
}
#dialog {
background: #ffffff none repeat scroll 0 0;
box-sizing: border-box;
height: 100%;
max-height: 80%;
max-width: 80%;
padding: 50px;
position: relative;
}

Related

Scroll bottom div on top of the div placed above

I have tow divs in a flex container, one containing the chart and another containing it's legends as below :
When I scroll on the div below, it should scroll up on the chart like so :
Here's my attempt at this with z-index and position absolute :
HTML -
<div className={`${style['chart__doughnut-wrapper-opportunity']} ${props.class}`}>
<div className={style.chart__data}>
<div className={style.chart__doughnut}>
<Chart
className="chart"
data={tabChartData}
width={props.width}
height={props.height}
options={optionsForGraphic(
props.type,
props.orientation,
tabChartData,
)}
/>
</div>
</div>
<div className={style.chart__legend}>
<div className={style.chart__table}>
<ChartLegend
chartType={'doughnut'}
page={props.page}
legendData={tabChartData}
percentage={percentage}
legendColor={legendColor}
legendStyle={legendStyle}
/>
</div>
</div>
</div>
CSS :
.chart__doughnut-wrapper-opportunity {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
max-height: 13.5rem;
margin: 1.25rem 0rem;
width: 100%;
border-bottom: #dadbdf solid 0.063rem;
.chart__data {
display: flex;
height: 100%;
align-items: center;
min-height: 13.5rem;
padding: 0 1rem 0 0;
width: 45%;
position: relative;
.chart__doughnut {
padding: 0;
width: 100%;
canvas {
z-index: 1;
position: relative;
}
}
}
.chart__legend {
display: flex;
// width: 100%;
position: absolute;
height: 20rem;
padding: 0 0 0 1rem;
z-index:10;
.chart__table {
display: flex;
flex-direction: column;
height: 20rem;
width: 100%;
word-wrap: break-word;
overflow-y: scroll;
-ms-overflow-style: none;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
}
}
Which has resulted in something like this :
I am stuck, not getting any ideas, please help.
Try applying the overflow to the chart_legend class and let's see

Centering certain div elements while keeping another element at the bottom

I have three elements in a div which itself is in another div. I want the first two elements of the inner div to be centered in relation to the outermost div and stacked on top of each other, while the third element should be at the bottom in relation to the outermost div as well. This is a WordPress project, which I am new to, so I don't want to change any of the div or class structure, just style the existing classes. I would prefer Flexbox-only solutions.
Here's the html:
<div class="outerDiv">
<div class="innerDiv">
<p class="e1"> Centered element 1 </p>
<p class="e2"> Centered element 2 </p>
<p> Bottom element </p>
</div>
</div>
Here's the relevant CSS:
.outerDiv{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 90px 0 0 0;
box-sizing: border-box;
}
.innerDiv {
align-self: center;
margin: 30px 30px 30px 30px;
}
.e1 {
margin: 10px 0;
}
.e2{
margin: 10px 0;
}
.innerDiv {
/*...*/
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.e1 {
margin: 10px 0;
margin-top: auto;
}
.e2{
margin: 10px 0;
margin-bottom: auto;
}
Edit: Added width/height properties to .innerDiv
Welcome to Stackoverflow. I've updated this to meet your new requirements:
.outerDiv {
width: 100%;
height: 600px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
text-align: center;
}
.innerDiv {
width: 50%;
height: 100%;
}
.e1 {
width: 100%;
height: 25%;
}
.e2 {
width: 100%;
height: 25%;
}
.e3 {
width: 50%;
height: 25%;
position: absolute;
bottom: 0;
}

How to set image size dynamically in ReactJS?

I have structure like this:
img {
width: auto;
height: 200px;
}
.cards {
display: flex;
justify-content: center;
margin-top: 2em;
width: 80%;
flex-wrap: wrap;
}
.card {
margin: 1em;
box-shadow: 0 0 6px #000;
object-fit: cover;
}
.info {
padding: 1em;
border-top: none;
}
<div class='cards'>
<div class="card">
<img src="https://picsum.photos/id/1004/5616/3744" alt="1004" />
<div class="info">
<h3>Greg Rakozy</h3>
<div><small>https://unsplash.com/photos/SSxIGsySh8o</small></div>
</div>
</div>
</div>
on computers with long width image is rendered a little wrong.
how can I fix this so that it displays correctly, i.e. sticks to the '.card' block?
First you need to limit the width of you main container:
.cards {
display: flex;
justify-content: center;
margin-top: 2em;
width: 80%;
flex-wrap: wrap;
max-width: 1440px; /* whatever you desire */
margin-left: auto; /* center the container */
margin-right: auto; /* center the container */
}
Then each image should take 100% for it's container:
.card {
margin: 1em;
box-shadow: 0 0 6px #000;
object-fit: cover;
flex: 0 0 25%; /* each card will be 25% width */
}
img {
width: 100%;
height: 200px;
object-fit: cover;
}
Adding those to .card class
width: 100%;
height: auto;
Google how to make image responsive with css, it's not related to React.
.card {
width: 100%;
height: auto;
}
You can either put those images in a div.img-container and set the div width & height like this.
.img-container {
width: 100%;
height: // as you want;
}
and then put that image inside .img-container and set the image width to 100%.
.container {
width: 350px;
height 350px;
border: 2px solid black;
border-radius: 5px;
}
.container .img-container {
width: 100%;
height: 200px;
}
.container .img-container img {
width: 100%;
height: 100%;
}
.container .card-info {
width: 100%;
height: auto;
}
<div class="container">
<div class="img-container">
<img src="https://picsum.photos/200">
</div>
<div class="card-info">
<h5>Title</h5>
<small>Your link here</small>
</div>
</div>
and either set image width 100% and height auto.

flex direction "row" inside a flexbox with flex-direction "column"

I am trying to make a navbar using flexbox. In my code I have the actual navbar wrapped with flex- direction:"row" to align the logo and the button.
Now I want to have the nav-inner (the beige div) under the navbar (that should be 100vw wide), but actually it sits next to the navbar.
I have tried to change the flex-direction to "column" inside my nav-menu div, but the Hamburger button goes out of the screen. Am I doing something wrong?
body {
margin: 0;
overflow: hidden;
}
/* defaults */
.safe-view {
display: flex;
height: 100vh;
}
.hamburger {
height: 30px;
width: 30px;
}
/**/
/* navbar */
.navbar {
position: sticky;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30px;
width: 100vw;
font-size: 1.2em;
height: 100px;
}
.nav-menu {
width: 100%;
display: flex;
flex-direction:row;
/*flex-direction:column;*/
position: absolute;
height: 100%;
overflow: hidden;
background-color: white;
}
.nav-inner {
height: 100%;
width: 100%;
background-color: blanchedalmond;
}
/**/
<div class="safe-view">
<div class="nav-menu">
<div class="navbar">
<h1>logo</h1>
<button class="hamburger"></button>
</div>
<div class="nav-inner"></div>
</div>
</div>
This is a CSS box-model issue. You need to add box-sizing: border-box. This will ensure that padding is included in calculation of the width.
*{
box-sizing: border-box;
}
By default box-sizing is set to content-box. This will only care about the element content and shift padding and border outside of the element. That is why you saw the button push out to the right! This can also help you to understand further.
Also, flex-direction for .nav-menu needs to be set to column in order to position .nav-inner below.
Heres an alternative. I removed padding and just used calc() function to create padding. But always include box-sizing:border-box in your CSS :)
*{
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.safe-view {
display: flex;
height: 100vh;
}
.navbar {
position: sticky;
display: flex;
flex-direction:row;
align-items: center;
justify-content: space-between;
width: calc(100vw - 60px);
margin: 0 auto;
font-size: 1.2em;
height: 100px;
}
.nav-menu {
width: 100%;
display: flex;
flex-direction:column;
position: absolute;
height: 100%;
overflow: hidden;
background-color: white;
}
.nav-inner {
height: 50px;
width: 100%;
background-color: blanchedalmond;
}
<div class="safe-view">
<div class="nav-menu">
<div class="navbar">
<h1 class="logo">logo</h1>
<button class="hamburger">button</button>
</div>
<div class="nav-inner"></div>
</div>
</div>

How do I vertically align a box to the center using CSS? [duplicate]

This question already has answers here:
How can I vertically center a div element for all browsers using CSS?
(48 answers)
Closed 5 years ago.
I've been learning CSS and am now practicing by trying to replicate basic websites, but I've stumbled across a problem!
I'm trying to vertically align a box so that it is always in the middle, and will automatically scale if I make the browser vertically smaller. So far I've tried to replicate what I've done horizontally (normally margin: 0 auto;) but it isn't working.
My relevant HTML and CSS so far look like this:
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Global Values */
html{
font-family: "Arial";
font-size: 16px;
line-height: 1.2;
height: 100%;
}
body{
background-color: #f9f9f9;
height: 100%;
}
.container{
display: block;
min-width: 240px;
max-width: 768px;
width: 100%;
/*----------------------------------------------*/
/* This is to make sure that the container height is always the same size as the browser. */
min-height: 100px;
height: 100%;
/*----------------------------------------------*/
margin: 0 auto;
text-align: center;
border-style: solid;
}
header{
border: solid;
min-height: 100px;
margin: auto 5%;
}
<body>
<div class="container">
<header>
<h1>Jon Phillips</h1>
<p>User Interface Designer</p>
<nav class="contact">
<p>Contact</p>
</nav>
</header>
</div>
</body>
I'm showing the borders so I can see what's going on, and am sure that (like horizontal centering) my margins need to be automatic. When I've done this horizontally, it's worked fine...
Does anyone have a recommendation on what to do??
Thanks in advance!
Flexbox is your friend! You need to add the following to your container styles
display: flex;
align-items: center;
justify-content: center;
We're setting the display to flex/flexbox with display: flex; and aligning everything to the center with align-items: center; and justify-content: center;
With all the vendor-prefixes it looks like:
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;
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Global Values */
html{
font-family: "Arial";
font-size: 16px;
line-height: 1.2;
height: 100%;
}
body{
background-color: #f9f9f9;
height: 100%;
}
.container{
display: block;
min-width: 240px;
max-width: 768px;
width: 100%;
/*----------------------------------------------*/
/* This is to make sure that the container height is always the same size as the browser. */
min-height: 100px;
height: 100%;
/*----------------------------------------------*/
margin: 0 auto;
text-align: center;
border-style: solid;
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;
}
header{
border: solid;
min-height: 100px;
margin: auto 5%;
}
<body>
<div class="container">
<header>
<h1>Jon Phillips</h1>
<p>User Interface Designer</p>
<nav class="contact">
<p>Contact</p>
</nav>
</header>
</div>
</body>
Check this: https://codepen.io/danieldd/pen/pdooVN
<div class="container">
<div class="item-centered"></div>
</div>
.container {
height: 400px;
width: 100%;
background-color: cyan;
display: flex; /*this is needed for centering*/
align-items: center; /*this center vertically childred elements*/
justify-content: center; /*this center horizontally childred elements*/
}
.item-centered {
height: 200px;
width: 200px;
background-color: red;
}
Sadly the auto margins trick only works horizontally. In CSS3, you can use another trick. You start with top: 50%; and then subtract half the height of your container using transform: translateY(-50%);. The perspective(1px) is just to correct the calculation to a whole pixel and prevent issues in some browsers. See the three lines I've added to your CSS:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Global Values */
html {
font-family: "Arial";
font-size: 16px;
line-height: 1.2;
height: 100%;
}
body {
background-color: #f9f9f9;
height: 100%;
}
.container {
display: block;
min-width: 240px;
max-width: 768px;
width: 100%;
/*----------------------------------------------*/
/* This is to make sure that the container height is always the same size as the browser. */
min-height: 100px;
height: 100%;
/*----------------------------------------------*/
margin: 0 auto;
text-align: center;
border-style: solid;
}
header {
border: solid;
min-height: 100px;
margin: auto 5%;
position: relative;
top: 50%;
transform: perspective(1px) translateY(-50%);
}
<body>
<div class="container">
<header>
<h1>Jon Phillips</h1>
<p>User Interface Designer</p>
<nav class="contact">
<a href="mailto:jon#jonphillips.ca" target="_blank">
<p>Contact</p>
</a>
</nav>
</header>
</div>
</body>
On the parent of the item that you're trying to center, you can just use display: flex; and the child should center inside (with the rest of the styles that you already have set up).
This could also be achieved using absolute positioning, though it would be a few more lines:
.parent {
position: relative;
}
.child {
/* Vertically center - will still need left / right & width adjustment otherwise */
position: absolute;
top: 50%;
transform: translateY(-50%);
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Global Values */
html{
font-family: "Arial";
font-size: 16px;
line-height: 1.2;
height: 100%;
}
body{
background-color: #f9f9f9;
height: 100%;
}
.container{
display: block;
min-width: 240px;
max-width: 768px;
width: 100%;
display: flex;
/*----------------------------------------------*/
/* This is to make sure that the container height is always the same size as the browser. */
min-height: 100px;
height: 100%;
/*----------------------------------------------*/
margin: 0 auto;
text-align: center;
border-style: solid;
}
header{
border: solid;
min-height: 100px;
margin: auto 5%;
width: 100%;
}
<body>
<div class="container">
<header>
<h1>Jon Phillips</h1>
<p>User Interface Designer</p>
<nav class="contact">
<p>Contact</p>
</nav>
</header>
</div>
</body>
There are different approuces to solve this problem, the easyest and with a good compatibility is the use of the "table-cell display", so in your case adding this to your CSS:
.container {
display:table-cell;
height:100%;
vertical-align:middle
}
The point is that a correct implementation of a table-cell should consider the parent element as a table, your parent element is the body itself, so do change your CSS into:
body{
background-color: #f9f9f9;
height: 100%;
width:100%;
display:table
}
http://jsfiddle.net/9tghnydg/
On a second though the height propriety on the .container is not strictly necessary, acting it as the unique cell of the body table:
.container {
display:table-cell;
vertical-align:middle
}
http://jsfiddle.net/9tghnydg/1/