contain image in 60%-height-div, while keeping aspect ratio - html

What I am trying to accomplish:
- create a pop-up div (fixed), centered in view
- this pop-up should be 60% height of the browser window
- the contents of the pop-up should be an image and a 'x' above the upper right corner of the image
- the height of the image should be maximal, considering it should be contained in the div together with the 'x'
- the aspect ratio of the image should be maintained
I tried the following code
<div class="pop-up">
<p class="exit-button">x</p>
<img class="image" src="safari.png" width="1200" height="630" alt="" title="" />
</div>
With CSS:
body {
background: #333;
}
.pop-up {
position: fixed;
height: 60%;
width: auto;
left:50%;
top:50%;
-webkit-transform:translate(-50%,-50%);
transform:translate(-50%,-50%);
background:yellow;
object-fit: contain;
}
.exit-button {
text-align: right;
margin: 0;
font-size: 300%;
}
.image {
height: 100%;
width: auto;
opacity:0.7;
}
This code is not solving the problem, the image is not contained in the (yellow) div, as can be seen in the following screen shot:
http://www.michielvisser.nl/tmp/screenshot.jpg
How to contain the image in the div with maximal height for the image in the div and maintain aspect ratio?
SOLUTION 1: Remove the height and width from .pop-up and change height:100% in .image to height:60vh. That works perfectly. Apparently the child (img) will not adjust to the parent (div), but the parent (div) will adjust to the child (img). Sounds like real life.
SOLUTION 2: Essentially the problem arises when the window is resized (except in firefox). The solution can be to redraw the image after a resize, this solves the problem:
$(window).resize(function(){
$('img').hide();
setTimeout(function(){ $('img').show(); }, 1);
});

Your problems are:
You have an inline width and height set on your image, which is overriding the CSS styles for width and height on that image
The margin from your X is pushing the image down since the X is wrapped in a <p> tag.
You don't need object-fit at all.
The simple way to solve #1 is to delete the inline width and height from the image tag and leave it to the stylesheet.
Number 2 can be solved by wrapping the X in a div instead of a p, or you can use a pseudo element for it. I have taken the latter approach in the snippet below.
To solve #3, just delete the style from the stylesheet. (Having this property set in Safari actually messed things up for me.)
This snippet is tested in Safari 10.1.1. Note how the placeholder image is quite large by default (1000x800), but it only displays as big as it can per the parent div.
Edit: Based on your comments, let's revise this further so that we dictate the size on the image, and just let the wrapper take up the size of the image.
So on our image, in order to get it to be 60% as tall as the screen, we can do:
img {
height: 60vh;
width: auto;
}
Then, in our parent, we won't specify a width or height at all, but we can do display: flex just to make sure it is big enough to fit its contents.
body {
background: #333;
}
.pop-up {
display: flex;
position: fixed;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background: yellow;
}
.exit {
color: black;
text-decoration: none;
text-align: center;
font-size: 300%;
display: block;
position: absolute;
top: -50px;
right: -40px;
width: 40px;
height: 50px;
}
.image {
height: 60vh;
width: auto;
opacity: 0.7;
}
<div class="pop-up">
X
<img class="image" src="http://placehold.it/1000x800" alt="" title="">
</div>

I put the image above the P tag and added some CSS to .exit-button and .image
From here you can adjust padding and sizing of the elements.
body {
background: #333;
}
.pop-up {
position: fixed;
height: 60%;
width: auto;
left:50%;
top:50%;
-webkit-transform:translate(-50%,-50%);
transform:translate(-50%,-50%);
background:yellow;
object-fit: contain;
}
.exit-button {
position: absolute;
text-align: right;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: 0;
font-size: 300%;
}
.image {
height: 100%;
width: auto;
opacity:0.7;
}
<div class="pop-up">
<img class="image" src="http://icons.iconarchive.com/icons/johanchalibert/mac-osx-yosemite/1024/safari-icon.png" width="1200" height="630" alt="" title="" />
<p class="exit-button">x</p>
</div>

I copied your code and edited it. Please tell me whether this is the output you wanted or not.
body {
background: #333;
}
.pop-up {
position: fixed;
height: 60%;
width: auto;
left:50%;
top:50%;
padding-top: 30px;
-webkit-transform:translate(-50%,-50%);
transform:translate(-50%,-50%);
background:yellow;
object-fit: contain;
}
.exit-button {
margin-top: -50px;
text-align: right;
margin-right: 0;
font-size: 300%;
}
.image {
margin-top: -20px;
height: 100%;
width: auto;
opacity:0.7;
}
<div class="pop-up">
<p class="exit-button">x</p>
<img class="image" src="safari.png" alt="" title="" />
</div>

Because of either needing to hardcode in the alignment of the image given the size or deal with weird convolution, I believe this is the best way:
Create a fixed overlay occupying the entirety of the screen, create a container of 60% height, align it in the center with flexbox and stick the image inside making it occupy the entire height. The aspect ratio will update automatically (only happens with height).
As for the button – give it absolute positioning and a right position of 0, and manually give the parent relative positioning (this is necessary).
<div id="popup">
<div id="container">
X
<img src="https://i.redd.it/gelilvo30mgz.jpg">
</div>
</div>
html,
body {
height: 100%;
}
#popup {
position: fixed;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
#container {
position: relative; !important // has to be specified for the children (anchor) to find the bound
height: 60%;
background: #333;
}
a {
right: 0;
position: absolute;
}
img {
height: 100%;
}
https://jsfiddle.net/L2nLjjxc/1/
I believe that's the least amount of convolution if you want it to be dynamic.

Related

make the webpage fit into the screen

Trying to make the webpage fit into the screen so that you don't have to scroll up or down, or left and right. And the image is centered. Here is the current code:
#copyright {
top: 0px;
right: 11;
z-index: index 1;
}
#image {
position: absolute;
height: 2;
width: 2;
z-index: index 2;
}
<a href="https://lensdump.com/i/rSRDHc">
<img id="image" src="https://i3.lensdump.com/i/rSRDHc.png" alt="rSRDHc.png" border="0" /></a>
<div id="copyright"> ©apple </div>
Overflow wouldn't work if you wanted to scroll down to show more of the page. To fix that, you would have to crop the white background out of the image, which I'm unsure of why it's there in the first place, and it would also be best to make the background transparent after you crop it, in case you wanted to change the background colour.
You had the right set to 11, but didn't specify a value (same as your width and height on the image), which doesn't work at all; you have to specify a value e.g pixels or rem. And z-index: index [num] also isn't valid, it's just z-index: [num].
The alt tag on your image is a png file, which doesn't make much sense, it should be a description, or the link to the image.
#copyright {
right: 11px;
}
#image {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) scale(.7);
z-index: -1;
}
body {
overflow: hidden;
}
<a href="https://lensdump.com/i/rSRDHc">
<img id="image" src="https://i3.lensdump.com/i/rSRDHc.png" alt="rSRDHc.png" border="0" /></a>
<div id="copyright"> ©apple </div>
You can achieve this with a containing div, flexbox, and the vh and vw declarations in css.
vh determines the view height, so 100vh is 100% of the window. With your assets I've stacked the image on 95% of the screen and the text below on 5%. vw works the same but for view width.
.container{
height: 95vh;
width: 100vw;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
#image{
width: 100%;
height: 100%;
}
#copyright{
height: 5vh;
width: 100vw;
text-align: center;
}
Here is a codepen: codepen

Center full screen image vertically

I want to center an full screen image vertically.
I can't define image in CSS because the image depends on URL parameters.
<div>
<img src="photo.jpg">
</div>
div {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
If I define my image CSS like this:
div img {
width: 100%;
height: 100%;
}
My image will stretch and be deformed in height to fit on screen.
If I define my image CSS like this (just without defining height):
div img {
width: 100%;
}
My image will not stretch/be deformed, but it will start at top: 0 of the image. What I want is the image to be centered vertically and the overflow of it's height to be hidden.
Basically I want the same behaviour I would get in CSS with background centered:
background: url(photo.jpg) no-repeat center;
background-size: cover;
EDIT: I forgot to mention that CSS object-fit: cover works on this but I'm looking for a more cross-browser solution since this property does not work in every browsers.
Try this css
div {
position: fixed;
top: 50%;
left: 0;
width: 100%;
height: 100%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
EDIT
also its a bad practice to give the image both height and width. this will always override the aspect ratio of the image and stretch it in some direction.
use this for img
div img {
width: 100%;
}
This will first position the division 50% form top. i.e. the image will now have its topmost part at 50% of the page height then the translate property will move the image upward by 50% of its height essentially centering the image
How about this:
div {
position:fixed;
top:0;
left:0;
width: 100px;
height: 100px;
border:1px solid red;
text-align:center;
line-height:100px;
overflow:hidden;
}
img {
vertical-align:middle;
border:1px solid black;
}
<div>
<img src="https://www.smallbusinesssaturdayuk.com/Images/Small-Business-Saturday-UK-Google-Plus.gif">
</div>
If you allow js, you can do this (assuming the image has id 'img'):
#img {
width: 100%;
position: absolute;
top: 50%;
}
A negative margin top needs to be set using js or jQuery (on resize):
$('#img').css('margin-top', '-'+($('#img').height()/2)+'px');

Make image scale with parent container when screen is re-sized

In my liquid layout, my div elements have the property position-fixed. This means that as I re-size the browser, all the elements remain in the same position but have shrunk or increased in size.
The problem is when I place a picture in one of my div elements, it does not scale to fit in my div element, therefore the image 'leaks' out of its div container.
What I need: a property on my div element and/or image so that the image stays the same size as the div container and when the page is re-sized, the image re-sizes as well. Here's what I have:
#div1 {
position: fixed;
background-color: blue;
width: 100%;
height: 10%;
opacity: .3;
}
#div2 {
background-color: green;
position: fixed;
opacity: .3;
left: 20%;
right: 20%;
top: 10%;
height: 40%;
width: 60%;
}
#div3 {
background-color: red;
opacity: .3;
position: fixed;
left: 20%;
right: 20%;
top: 50%;
height: 40%;
width: 60%;
}
#div4 {
background-color: tan;
opacity: .3;
position: fixed;
height: 80%;
right: 80%;
width: 20%;
top: 10%;
}
#div5 {
background-color: black;
opacity: .3;
position: fixed;
height: 80%;
width: 20%;
left: 80%;
top: 10%;
}
#div6 {
background-color: purple;
opacity: .3;
position: fixed;
top: 90%;
width: 100%;
height: 10%;
}
img {}
<div id="div1">
<p>div1</p>
</div>
<div id="div2">
<figure>
<img class="pictures" src="assets/me.jpg" />
<figcaption>
This is a picture.
</figcaption>
</figure>
</div>
<div id="div3">
<header>
<h1>Introducing Me</h1>
</header>
<p>div3</p>
<p>Hello eveyrone i am adan ramirez</p>
</div>
<div id="div4">
<p>div4</p>
</div>
<div id="div5">
<p>div5</p>
</div>
<div id="div6">
<p>div6</p>
</div>
make image background-image: url(..img);
and apply background-size: cover; on the same div.
The key here is cover property value as it tells browser to resize image while keeping aspect ratio to fit all sides.
#Sphinxxx suggested to use background-size: contain; which solved OP problem;`
Try this:
img {
height: 100%;
width: 100%;
object-fit: contain;
}
object-fit is a pretty cool CSS3 property.
Used with the contain value the image will increase or decrease in size within its container while maintaining its aspect-ratio.
Here's how CSS-Tricks describes it:
The object-fit property defines how an element responds to the height
and width of its content box. It's intended for images, videos and
other embeddable media formats in conjunction with the object-position
property. Used by itself, object-fit lets us crop an inline image by
giving us fine-grained control over how it squishes and stretches
inside its box.
Because browser support for this property is still somewhat weak, here's a polyfill that covers all major browsers including IE9: Polyfill for CSS object-fit property
For a deeper look here are a few references:
W3C CSS Image Values and Replaced Content Module Level 3
MDN object-fit
CSS-Tricks `object-fit
Have you tried :
img {
width: 100%;
}
Try:
img {
max-width: 100%;
max-height: 100%;
}
figure {
height: 100%;
width: 100%;
margin: 0;
}
figure is the parent element, so you need to set it's height/width as well. Also, the default styling on figure includes a margin, so you need to remove that to keep the image inside of the parent div. Also, you may need to make the max-height smaller to account for the caption if you want to keep that inside of the parent div.
You can also use width and height instead of max-* if you want the image to always fill the parent regardless of its native size.

How to "crop" a rectangular image into a square with CSS?

I know that it is impossible to actually modify an image with CSS, which is why I put crop in quotes.
What I'd like to do is take rectangular images and use CSS to make them appear square without distorting the image at all.
I'd basically like to turn this:
Into this:
A pure CSS solution with no wrapper div or other useless code:
img {
object-fit: cover;
width: 230px;
height: 230px;
}
Assuming they do not have to be in IMG tags...
HTML:
<div class="thumb1">
</div>
CSS:
.thumb1 {
background: url(blah.jpg) 50% 50% no-repeat; /* 50% 50% centers image in div */
width: 250px;
height: 250px;
}
.thumb1:hover { YOUR HOVER STYLES HERE }
EDIT: If the div needs to link somewhere just adjust HTML and Styles like so:
HTML:
<div class="thumb1">
Link
</div>
CSS:
.thumb1 {
background: url(blah.jpg) 50% 50% no-repeat; /* 50% 50% centers image in div */
width: 250px;
height: 250px;
}
.thumb1 a {
display: block;
width: 250px;
height: 250px;
}
.thumb1 a:hover { YOUR HOVER STYLES HERE }
Note this could also be modified to be responsive, for example % widths and heights etc.
If the image is in a container with a responsive width:
.rect-img-container {
position: relative;
}
.rect-img-container::after {
content: "";
display: block;
padding-bottom: 100%;
}
.rect-img {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="rect-img-container">
<img class="rect-img" src="https://picsum.photos/id/0/367/267" alt="">
</div>
(edit: updated from sass to plain css)
(edit: Added dummy image for reference)
Place your image in a div.
Give your div explicit square dimensions.
Set the CSS overflow property on the div to hidden (overflow:hidden).
Put your imagine inside the div.
Profit.
For example:
<div style="width:200px;height:200px;overflow:hidden">
<img src="foo.png" />
</div>
Using background-size:cover - http://codepen.io/anon/pen/RNyKzB
CSS:
.image-container {
background-image: url('http://i.stack.imgur.com/GA6bB.png');
background-size:cover;
background-repeat:no-repeat;
width:250px;
height:250px;
}
Markup:
<div class="image-container"></div>
I actually came across this same problem recently and ended up with a slightly different approach (I wasn't able to use background images). It does require a tiny bit of jQuery though to determine the orientation of the images (I' sure you could use plain JS instead though).
I wrote a blog post about it if you are interested in more explaination but the code is pretty simple:
HTML:
<ul class="cropped-images">
<li><img src="http://fredparke.com/sites/default/files/cat-portrait.jpg" /></li>
<li><img src="http://fredparke.com/sites/default/files/cat-landscape.jpg" /></li>
</ul>
CSS:
li {
width: 150px; // Or whatever you want.
height: 150px; // Or whatever you want.
overflow: hidden;
margin: 10px;
display: inline-block;
vertical-align: top;
}
li img {
max-width: 100%;
height: auto;
width: auto;
}
li img.landscape {
max-width: none;
max-height: 100%;
}
jQuery:
$( document ).ready(function() {
$('.cropped-images img').each(function() {
if ($(this).width() > $(this).height()) {
$(this).addClass('landscape');
}
});
});
Check out CSS aspect-ratio
https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
.square-image{
width: 50%;
background-image: url('https://picsum.photos/id/0/367/267');
background-size: cover;
background-position: center;
aspect-ratio: 1/1;
}
<div class="square-image"></div>
You can also do this with a regular img tag as follows
.square-image{
width: 50%;
object-fit: cover; /* Required to prevent the image from stretching, use the object-position property to adjust the visible area */
aspect-ratio: 1/1;
}
<img src="https://picsum.photos/id/0/367/267" class="square-image"/>
Today you can use aspect-ratio:
img {
aspect-ratio: 1 / 1;
}
It has wide support amongst modern browsers as well:
https://caniuse.com/mdn-css_properties_aspect-ratio
object-fit: cover will do exactly what you need.
But it might not work on IE/Edge. Follow as shown below to fix it with just CSS to work on all browsers.
The approach I took was to position the image inside the container with absolute and then place it right at the centre using the combination:
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
Once it is in the centre, I give to the image,
// For vertical blocks (i.e., where height is greater than width)
height: 100%;
width: auto;
// For Horizontal blocks (i.e., where width is greater than height)
height: auto;
width: 100%;
This makes the image get the effect of Object-fit:cover.
Here is a demonstration of the above logic.
https://jsfiddle.net/furqan_694/s3xLe1gp/
This logic works in all browsers.
Original Image
Vertically Cropped
Horizontally Cropped
Square Container
I had a similar issue and could not "compromise" with background images.
I came up with this.
<div class="container">
<img src="http://lorempixel.com/800x600/nature">
</div>
.container {
position: relative;
width: 25%; /* whatever width you want. I was implementing this in a 4 tile grid pattern. I used javascript to set height equal to width */
border: 2px solid #fff; /* just to separate the images */
overflow: hidden; /* "crop" the image */
background: #000; /* incase the image is wider than tall/taller than wide */
}
.container img {
position: absolute;
display: block;
height: 100%; /* all images at least fill the height */
top: 50%; /* top, left, transform trick to vertically and horizontally center image */
left: 50%;
transform: translate3d(-50%,-50%,0);
}
//assuming you're using jQuery
var h = $('.container').outerWidth();
$('.container').css({height: h + 'px'});
Hope this helps!
Example:
https://jsfiddle.net/cfbuwxmr/1/
Use CSS: overflow:
.thumb {
width:230px;
height:230px;
overflow:hidden
}
Either use a div with square dimensions with the image inside with the .testimg class:
.test {
width: 307px;
height: 307px;
overflow:hidden
}
.testimg {
margin-left: -76px
}
or a square div with a background of the image.
.test2 {
width: 307px;
height: 307px;
background: url(http://i.stack.imgur.com/GA6bB.png) 50% 50%
}
Here's some examples: http://jsfiddle.net/QqCLC/1/
UPDATED SO THE IMAGE CENTRES
.test {
width: 307px;
height: 307px;
overflow: hidden
}
.testimg {
margin-left: -76px
}
.test2 {
width: 307px;
height: 307px;
background: url(http://i.stack.imgur.com/GA6bB.png) 50% 50%
}
<div class="test"><img src="http://i.stack.imgur.com/GA6bB.png" width="460" height="307" class="testimg" /></div>
<div class="test2"></div>
I came with a different approach. You basically have to crop the rectangular image to fit it inside the square is all there is to it. Best approach is if the image width is greater than the height, then you crop the image alittle from left and right side of the image. If the image height is greater than the image width then you crop the bottom of the image. Here is my solution. I needed a little help from PHP though.
<div style="position: relative; width: 154px; height: 154px; overflow: hidden;">
<?php
//get image dimmensions whichever way you like. I used imgaick
$image = new Imagick("myimage.png");
$width = $image->getImageWidth();
$height = $image->getImageHeight();
if($width > $height){
?>
<img src="myimage.png" style="display: block; position: absolute; top: 0px; left: 50%; transform: translateX(-50%); -ms-transform: translateX(-50%); -webkit-transform: translateX(-50%); height: 100%; " />
<?php
}else{
?>
<img src="myimage.png" style="display: block; position: absolute; top: 0px; left: 0px; width: 100%; " />
<?php
}
?>
</div>

Square DIV with Content in a Fluid Layout

SO,
I've created a four-column fluid-width layout for a site, and I'm working on placing a fluid square DIV within one of my columns. There are a few techniques I've found to achieve this - namely, setting padding-bottom to the same percentage as the width - but none of these seem to work when the DIV contains content.
Is there a way to maintain a 1:1 (square) ratio on a fluid DIV when that DIV contains content?
Here's my HTML:
<div id="leftmostcolumn">
<div id="logo"></div>
</div>
<div id="leftcolumn"></div>
<div id="rightcolumn"></div>
<div id="rightmostcolumn"></div>
And my CSS:
body {
width: 100%;
height: 100%;
background-color: red;
}
#leftmostcolumn {
position: absolute;
top: 0;
left: 0;
width: 25%;
height: 100%;
background-color: blue;
}
#leftcolumn {
position: absolute;
top: 0;
left: 25%;
width: 25%;
height: 100%;
background-color: green;
}
#rightcolumn {
position: absolute;
top: 0;
left: 50%;
width: 25%;
height: 100%;
background-color: yellow;
}
#rightmostcolumn {
position: absolute;
top: 0;
left: 75%;
width: 25%;
height: 100%;
background-color: gray;
}
#logo {
width:100%;
padding-bottom:100%;
background-color: #aa2d2d;
color: white;
}
​​
And here's a JsFiddle.
The DIV "logo" is the one I'm trying to maintain as a square. Right now, I've used the padding-bottom approach but that doesn't do the trick when there's content in the DIV. Any input is greatly appreciated!
Marca
EDIT:
Getting there...I'm adapting a script I found to find the width of the DIV and then apply that value to the height to keep it a square. However, as it stands now the script doesn't constantly resize the DIV, and it won't allow it to shrink below a certain size. Any thoughts on how to correct either of these issues?
HTML:
<div id="box"></div>
CSS:
​ #box { width: 75%; height: 50px; background-color: black; }​
JQUERY:
$("#box").css("height", function() {
return $(this).width();
});
JsFiddle is here.
This is something I've actually been messing around with for a while, and have come up with a quasi (but not entirely) hacky, CSS-only solution that seems to work on most browsers in the past decade. The trick is to use images, and positioning in a tricky fashion. Consider the following (simplification) of your code.
Markup:
<div class="sqr_box">
your content goes here!
</div>
CSS:
.sqr_box
{
width: 50%; /* or 100px, or 20em, or whatever you want */
border: solid 2px pink;
background-color: grey;
color: white;
}
Now, we can't set the height in terms of percent, so we won't; instead, first we'll go into Photoshop, and make an image that is 2x2 px, transparent, or background-colored. Next we'll add the following to your markup:
<div class="sqr_box">
<img src="images/sizers/2x2.png" class="sizer">
<div class="content">your content goes here!</div>
</div>
and THIS to your CSS:
.sqr_box
{
width: 50%; /* or 100px, or 20em, or whatever you want */
position: relative; /* static positioning is less than ideal for this scenario */
}
.sqr_box > img.sizer
{
display: block; /* images default to an inline-block like thing */
width: 100%;
height: auto; /* CLUTCH!!! this ensures that the image's height changes to maintain proportions with it's width */
visibility: hidden;
}
.sqr_box > .content
{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%; /* Our parent element now has a dynamically assigned height, this will work */
border: solid 2px pink;
background-color: grey;
color: white;
}
Best of all, this will work for any sized ratio of box you'd want! Just change the proportions of the image!
Hope this is all still relevant to you, 3 months later.
-Sandy
Put all four columns in one div. set that div to 100% width and set the font size to 100em
Have each of your four columns have a width of 25em instead of 25%
Have your logo width and height set to 25em each