Force broken image to preserve hard-coded aspect ratio - html

I'm working on a responsive web page with images that may be larger than the max-width of a mobile browser screen. In the example below, I'm using an image from https://stackoverflow.com/company which is 975x573.
Consider this snippet.
img {
max-width: 100%;
height: auto;
}
<img height="573" width="975" src="https://cdn.sstatic.net/Sites/stackoverflow/company/Img/photos/big/1.jpg?v=17b956bfb68e">
<p>test</p>
<img height="573" width="975" src="https://stackoverflow.com/missing-image.png">
<p>test</p>
This sample includes two images, one that exists, and one that doesn't exist.
I want the image boxes for both images to be the same height, 100% width with the aspect ratio preserved.
Instead, the existing image is correctly resized with its aspect ratio preserved, but the broken image is 16x16, which (in my full site) makes my layout look weird.
How do I fix this example? (Pure CSS only, please.)

It doesn't seem to be possible to style broken images the way I want. The only workaround I can find is to use a wrapper div, force the div to maintain a fixed aspect ratio, and to force the image to fill its wrapper parent.
There are a bunch of techniques for doing that in the link above. Here's one, for example.
.wrapper {
max-width: 100%;
padding-bottom: 58.77%; /* 573/975 */
position: relative;
}
img {
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
max-width: 100%;
max-height: 100%;
}
<div class="wrapper"><img src="https://cdn.sstatic.net/Sites/stackoverflow/company/Img/photos/big/1.jpg?v=17b956bfb68e"></div>
<p>test</p>
<div class="wrapper"><img src="https://stackoverflow.com/missing-image.png"></div>
<p>test</p>

Let me be clear, the "broken image" is just browsers rendered image to show you it is broken and you can not access to that "icon". So that, in some browser it is not be shown because some browsers not support.
The best solution to get the same result that you expected is using background image for your image element. Please check my codes snippet bellow:
You have to define the Aspect Ratio, in my codes I had defined the Aspect Ratio by division between height and width => 573/975.
More info: https://www.w3schools.com/howto/howto_css_aspect_ratio.asp
img {
width: 100%;
height: auto;
}
.img-cover {
background-image: url(http://via.placeholder.com/975x573);
background-repeat: no-repeat;
background-size: cover;
width: 100%;
padding-top: 58.769%; /* Aspect Ratio from 573/975 */
position: relative; /* If you want text inside of it */
}
.inner {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
<div class="img-cover">
<div class="inner">
<img height="573" width="975" src="https://cdn.sstatic.net/Sites/stackoverflow/company/Img/photos/big/1.jpg?v=17b956bfb68e">
</div>
</div>
<p>test</p>
<div class="img-cover">
<div class="inner">
<img height="573" width="975" src="https://stackoverflow.com/missing-image.png">
</div>
</div>
<p>test</p>

Related

Carousell and fixed image size

I'm new to bootstrap and CSS especially something like carousel
so far this is my code
<div class="container">
<div class="row">
<div class="carousel-item <%# Eval("Aclass") %>">
<img class='img-fluid w-100' alt="slide Responsive image" src='<%# Eval("ImageValue") %>' />
<div/>
</div>
</div>
It works well to show the image but the problem come when the image size are different.
Sometimes I have to scroll up and down to scroll for full image, how do I force it to let say 500 x 500 px image no matter what is the original image size is.
I have a solution which help you to solve this issue but after applying this solutions some of your image portion will cut if you are okay with that then bind your image in a div.
Like this example in snippet:
.image_container {
width: 100%;
padding-top: 40%; /*height of the image depands on this*/
overflow: hidden;
position: relative;
}
.image_container img {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
min-width: 100%;
max-width: 100%;
min-height: 100%;
max-height: 100%;
object-fit: cover;
}
<div class="image_container">
<img src="https://i.pinimg.com/originals/1f/87/90/1f8790df8b450fbf5c3b4a6b9db4f822.jpg" alt="image">
</div>
This solution display the center portion of the image and always fill the container and also cut some portion of your image.
Note: please add one extra div class for this, don't consider carousel-item class as an image container.

Image Aspect Fill Mode: CSS

I am an iOS developer. We have aspect fill property on of imageview. This property lets image fill the target viewport or container but keeping aspect ratio.
Now fill works in certain way which I couldn't achieve using pure css. I am gonna write down the code below. And explaining my need is struggle to phrase it in english so please try to endure it and have patience. So here it is:
Aspect Fill: This only fills with scale factor that is required. For example: If image is bigger than viewport size then image will scale down maintaining aspect ratio until it gets smaller than viewport else it will be "fit" effect. It has to fill the viewport. Extra part that is out of viewport's bounds will be clipped off.
If image is smaller than viewport then image will scale up maintaining aspect ratio until it just fills the viewport. Extra part that is out of viewport's bounds will be clipped off.
Scale factor of fill is important. I hope I explained my need. After trying to learn around the web to achieve I came up with below code. This code doesn't fill the way I want. It maintains aspect ratio but fills with 100% zoom or scale.
.page-container, .page {
width: 320px;
height: 480px;
}
.page {
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.page-image {
flex-shrink: 0;
min-width: 100%;
min-height: 100%;
}
<div class="page-container">
<div class="page">
<img class="page-image" src="https://images.unsplash.com/photo-1495974887311-a817001ebd74" alt="">
</div>
</div>
You can look at that original image in unsplash link.
You can test on smaller image: https://upload.wikimedia.org/wikipedia/commons/5/50/Salta-VallesCalchaquies-P3140151.JPG
Can this mode be achieved in pure css or Do i need javascript to manipulate the new size for every image that aspect-fills the viewport according to my requirement?
You can use object-fit: cover; in your image-class.
You also need to add width and height to your image.
(Note: It doesn't work on Internet Explorer but you could add a polyfill like this! to make it work there as well).
Here's the example, based on your code:
.page-container, .page {
width: 320px;
height: 480px;
}
.page {
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.page-image {
flex-shrink: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="page-container">
<div class="page">
<img class="page-image" src="https://images.unsplash.com/photo-1495974887311-a817001ebd74" alt="">
</div>
</div>

Responsive images resizing

I'm trying to create a carousel of images inspired on the one in airbnb (https://www.airbnb.it/rooms/5382144?location=Roma%20Termini%2C%20Piazza%20dei%20Cinquecento%2C%20Roma%2C%20RM)
If you use the link above, you will notice the follows:
If you change the WIDTH of your window, the image will resize accordingly
If you change the HEIGHT of your window, the image will also resize accordingly
All the images are resized based on the height of the smallest image. That means that if I have two images, one in landscape and one in portrait, the portrait image will resize to fit the height of the landscape image.
Now, I've been able to achive the number 1 and 2, but I'm struggling to achieve the number 3 using just CSS.
I did a jsfiddle to show you what I'm talking about
https://jsfiddle.net/hvbvhc0q/5/
<div class="container">
<div class="">
<div class="container-img">
<img src="https://a0.muscache.com/im/pictures/67194098/f47fcd01_original.jpg?aki_policy=x_large" style="border: 2px solid blue">
</div>
<div class="container-img">
<img src="https://a0.muscache.com/im/pictures/67194187/634b2de1_original.jpg?aki_policy=x_large" style="border: 2px solid red">
</div>
</div>
</div>
.container-img img {
position: absolute;
max-height: 100%;
left: 0;
right: 0;
margin: 0 auto;
max-width: 100%;
}
If you resize in width or height the preview box, you will notice that everything is perfectly responsive. But the problem is that the portrait image (red border) doesn't fit the landscape image (blu border).
Said in other words: I want to keep the aspect ratio, but I want the portrait image to have the max-height equals to the height of the landscape (but of course without specifing any "fixed" height in px).
Can anyone help me? Thank you so much!
I don't know what do you need, but, try this css code:
.container-img img {
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
max-width: 100%;
max-height: 500px; /*change for your necessity*/
}
But if you want to use a carousel component, I suggest for you that you research plugins js for this, like this link: https://github.com/yadhu/airbnb
Ok, I don't now why it works, but I did it!! :D
Here you can find the working fiddle: https://jsfiddle.net/g8t2o9ft/6/
This is the code and css:
<div class="container">
<div class="container-inner">
<div>
<div>
<img src="https://a0.muscache.com/im/pictures/67194046/877580d4_original.jpg?aki_policy=xx_large" style="border: 2px solid blue">
</div>
<div>
<img src="https://a0.muscache.com/im/pictures/67194187/634b2de1_original.jpg?aki_policy=x_large" style="border: 2px solid red">
</div>
</div>
</div>
</div>
img {
position: absolute;
height: 100%;
left: 0;
right: 0;
margin: 0 auto;
max-width: 100%;
}
.container-inner {
position: relative;
padding-bottom: 65%;
}
.container {
max-width: 105vh;
}
As you can see, it's responsive for width (goal 1, easy), it's responive for height (goal 2, thanks to the rule max-width: 105vh) and the two images follow the same height keeping the same aspect ratio (goal 3).
Basically the trick that allows me to achieve the goal 3 is to apply these rules to the parent div:
.container-inner{
position: relative;
padding-bottom: 65%;
}
But I still don't really know why it works (I copied it from airbnb css)
Thank you so much to everyone who answered this question!
It seems you are using bootstrap (correct me if I am wrong). If so use class img-responsive for the img tag as below.
<img class="img-responsive" src="logo.png" alt="logo">

Place div below element with fixed position and 100% height

I have two divs: #lookbookHeader and #introContent. #lookbookHeader has a video in it with position: fixed, height: 100% and height: auto, which I followed from this tutorial. I would like #introContent to be below #lookbookHeader, regardless of the height, as you see on this page. I am trying to create a page where the video is full viewport when the page loads, and you can scroll down to see additional content below.
I have tried every combination of positioning, floating and display on these two elements to try to get this to work and I just can't get it! Currently #lookbookHeader has no styles because it doesn't seem to matter what I apply to it, as the video styles override it when I apply position fixed. If I don't have fixed on the video, then it doesn't scale or size correctly with width/height. What am I missing?
I know I can use jQuery or JavaScript to get the height of #lookbookHeader when the page loads but wondering if there is a way to do this with CSS only. You can see the page here.
I have checked other posts on SO, such as this one, but all seem to reference a fixed element with a set height which is not the case here.
HTML
<div id="lookbookHeader">
<video autoplay poster="http://lcoawebservices.com/assets/lp_stainless_SliderStop_5.jpg" id="bgvid">
<source src="http://lcoawebservices.com/assets/lp_stainless_Transition_5.webm" type="video/webm">
<source src="http://lcoawebservices.com/assets/lp_stainless_Transition_5.mp4" type="video/mp4">
</video>
<div id="headerContentContainer">
<h1>Lookbook: Spring 2015</h1>
<div class="initial-arrow-small"></div>
</div>
</div>
</div>
<div id="introContent">
<h2>Bienvenue</h2>
<p>Lorem ipsum dolor sit amet</p>
<div class="block red">one</div>
<div class="block blue">two</div>
<div class="block yellow">three</div>
<div class="block green">four</div>
</div>
CSS
#introContent {
max-width: 100%;
height: auto;
background-color: #fff;
}
#lookbookHeader video#bgvid {
position: fixed;
right: 0;
bottom: 0;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: -100;
background: url(http://lcoawebservices.com/assets/lp_stainless_SliderStop_5.jpg) no-repeat;
background-size: cover;
display: block;
}
Add a top margin to accomplish this. First you need to include html on the body styles:
html,body { //add html
width: 100%;
height: 100%;
font-family: Helvetica, Arial, sans-serif;
font-size: 11px;
margin: 0;
padding: 0;
}
Then add height:100% to .container (for it's children). Then you can set the height and margin on .introContent. Also you have floated elements inside .introContent that you're not clearing. You can correct that by adding overflow: hidden:
#introContent {
min-height: 100%; //add min-height
max-width: 100%;
height: auto;
background-color: red; //changed so you can see the container better
overflow: hidden; //add to clear floats
margin: 50% 0 0; //add margin from top
}
FIDDLE
UPDATE
I have a better solution. Sometimes you just overthink things. Just simply add a blank div above the content like so:
<div class="spacer"></div>
<div id="introContent">
....
and set it to:
.spacer{
height: 100%;
width: 100%;
}
That will take up the height of the screen and bump your content down below
BETTER FIDDLE

How to make centre cropped image responsive?

Based on an existing answer, I have managed to centre crop an image. I am having trouble making the centre cropped image responsive, though.
Question
When I reduce the size of the web browser window, the centre cropped image does not scale down nicely. Instead, it maintains it's fixed height and width and spills out of the view-port. The problem is perhaps demonstrated more clearly with a Fiddle.
How can I make the centre cropped image scale down nicely? Ideally the centre cropped image will scale down nicely while still being cropped and maintaining a similar aspect ratio.
.centered-container {
max-width: 960px;
margin: auto;
}
.center-cropped-img {
width: 640px;
height: 360px;
overflow: hidden;
margin: 10px auto;
border: 1px red solid;
position: relative;
}
.center-cropped-img img {
position: absolute;
left: -100%;
right: -100%;
top: -100%;
bottom: -100%;
margin: auto;
min-height: 100%;
min-width: 100%;
}
<div class="centered-container">
<div class="center-cropped-img">
<img src="http://i.imgur.com/Ag2ZCgz.png" alt="" />
</div>
<div class="center-cropped-img">
<img src="http://i.imgur.com/BQUgmlB.png" alt="" />
</div>
</div>
Again, here is a Fiddle that perhaps demonstrates the problem better than in prose.
Read the comments in the code for an explanation.
JSFiddle
HTML
<div class="container">
<img src="http://i.imgur.com/Ag2ZCgz.png" alt="" />
</div>
<div class="container">
<img src="http://i.imgur.com/BQUgmlB.png" alt="" />
</div>
CSS
/*some basic markup for a flexible container to crop the image*/
.container {
width: 80%;
border: 3px red double;
margin: 50px auto;
padding:0;
overflow: hidden;/*do not show image that is overflowing*/
background-color: yellow;
}
.container img {
display: block;
width: 200%;/** (1 / part of the total image width you want shown)*100% In this example you want to show 50% of the image-width**/
margin-left:-50%;/*move the image to the left, removing that content from view (and making content on the right appear). -0% will show the left side of the image. The negative value of the defined width in the rule before this one + 100% will show you the right side of the image. I guess you can figure the rest out by changing this value.*/
margin-top: -25%;/*changing the top and bottom values is a bit of a pain. After some trial and error (in google chrome) it appears they are based on the width of the image container, not the height (how unusual is that!!!). So putting -100% in this value would (re)move the image up by the px value of the width of the #container div. If you are using css sprites you should avoid setting this value other than 0%.
Alternatively do some math on the original dimensions of the image: -(vertical pixels you want off the image)/(image width)* 100% should work for pixel precision).
The good news is that the image scales with the #container div. So the image grows and shrinks with the container showing the exact same part of the image (and not showing more/less content).*/
margin-bottom:-25%;/*(re)move some of the bottom part of the image. See margin-top for more (works identical)*/
}
Use the padding hack.
U need a container, which you set to be a width in percent, height of 0 and padding on the bottom to create the aspect ratio you are looking for.
If you can set your image as a background it's even easier.
I have written a sass mixin for that, and also a small tutorial on my blog which comes with a little more extensive explanation: http://bekreatief.blogspot.ch/2014/09/padding-hack-sass-faux-color-overlay.html
If you need to have your image in an image tag, let me know, it's possible as well, but not as fast
Does adding this (fiddle) to .center-cropped-img achieve what you want? or do you not want to change the area that is being cropped?
max-width: 640px;
width: 100%;
Does this Fiddle do the right cropping?
With the following CSS we can maintain the aspect ratio of the container when resizing the window.
width: 640px;
max-width: 100%;
height: 0;
padding-bottom: 50%; // 320px or lower (half of the width)
The following solution uses CSS background-size property. The image is placed in the background. The <img> tag is used so that search engines can see the image.
/* responsive 40% wide, 4:3 aspect ratio container */
.centered-image {
width: 40%;
padding-top: 30%;
background-position: center center;
/* optional */
margin: 1em auto;
box-shadow: 0 0 .5em .25em black;
}
.centered-image.cropped {
background-size: cover;
}
.centered-image.scaled {
background-size: contain;
background-repeat: no-repeat;
}
/* use your favorite text hiding technique */
.centered-image img {
display: none;
}
/* miscellaneous */
body {
margin: 0;
padding: 0;
}
h1 {
width: 40%;
margin: 1em auto;
font: bold medium monospace;
}
<h1>Cropped to Fit</h1>
<div class="centered-image cropped" style="background-image: url(http://lorempixel.com/400/400/sports/1/);">
<img src="http://lorempixel.com/400/400/sports/1/" width="400" height="400" alt="">
</div>
<div class="centered-image cropped" style="background-image: url(http://lorempixel.com/400/200/sports/2/);">
<img src="http://lorempixel.com/400/200/sports/2/" width="400" height="200" alt="">
</div>
<div class="centered-image cropped" style="background-image: url(http://lorempixel.com/200/400/sports/3/);">
<img src="http://lorempixel.com/200/400/sports/3/" width="200" height="400" alt="">
</div>
<h1>Scaled to Fit</h1>
<div class="centered-image scaled" style="background-image: url(http://lorempixel.com/400/400/sports/1/);">
<img src="http://lorempixel.com/400/400/sports/1/" width="400" height="400" alt="">
</div>
<div class="centered-image scaled" style="background-image: url(http://lorempixel.com/400/200/sports/2/);">
<img src="http://lorempixel.com/400/200/sports/2/" width="400" height="200" alt="">
</div>
<div class="centered-image scaled" style="background-image: url(http://lorempixel.com/200/400/sports/3/);">
<img src="http://lorempixel.com/200/400/sports/3/" width="200" height="400" alt="">
</div>
I have tried with a script. I simply created a function and called on loading and re-sizing.
jQuery
$(document).ready(function () {
heightMan();
$(window).resize(function () {
heightMan();
});
});
function heightMan() {
var winHeight = $(window).height();
var winHeight_50 = (winHeight / 2) - 20;
var container_node = $('.center-cropped-img');
var container_height = container_node.height();
container_height = winHeight_50;
container_node.css('height', container_height);
}
CSS Changes
.center-cropped-img {
width: 64%;
overflow: hidden;
margin: 10px auto;
border: 1px red solid;
position: relative;
}
See in action.
just give width in % instead of px .
.center-cropped-img {
width: 640px;// add in %
height: auto;
overflow: hidden;
margin: 10px auto;
border: 1px red solid;
position: relative;
}