CSS banner image, doesn't scale beyond the parent element - css

I'm trying to style a typcial banner image for a site, so that for narrower viewports the vertical height is maintained and the image effectively stays the same size by going beyond the parent element horizontally. (I think this is fairly typical banner image behaviour - but feel free to correct me if I'm wrong).
(browser target is ie10 and up). The below incorrectly keeps the image ratio and at 100% width so that if fails to match the height of the parent.
The current html is just an img inside a div tag
<div class="banner">
<img class="img-fluid" src="somepic.jpg" />
</div>
Where the css classes used are:
.banner {
content: "";
position: absolute;
width: 100%;
top: 0;
left: 0;
height: 780px;
}
and img-fluid is a bootstrap(4) class with
img-fluid {
max-width: 100%;
height: auto;
}

Use a background-image instead, there are a couple interesting behaviours that can be used to achieve different results.
Here's my take:
.banner {
content: "";
position: absolute;
width: 100%;
top: 0;
left: 0;
height: 780px;
background-image:url('somepic.jpg');
background-size:cover;
}
The key here is background-size:cover;, it will make sure the image stretches to cover the full width and height while keeping its ratio. That means on very wide screens, it will be made larger, cutting some height. But on thinner resolutions you'll get the desired output.

Related

Scale dynamic image with different widths and heights

I have image in the header and populate its source from the database, so it has different width and height. Image dimensions could be max 2000x2000px. I'm trying to scale it but when it's very large e.g more than 1000px it's very big and it's not looking good.
This is what I currently have.
#image {
position: absolute;
display: block;
top: 20px;
left: 20px;
height: 50px;
}
<div id="wrapper">
<img src="some-dynamic-url" id="image">
</div>
I've also tried with background-size: cover but it's not stretched and how to preserve the aspect ratio and set max-width and max-height not to be so big?
Updated. My current code is the following:
#image {
display: block;
top: 20px;
left: 20px;
width: 100%;
max-width: 170px;
}
<div id="wrapper">
<img src="some-dynamic-url" id="image">
</div>
Will the height always be 50px? If not, you should remove that from your CSS and instead use height: auto;.
Also, if it starts to not look so great at 1000px by 1000px, maybe set width: 1000px; and max-width: 85%; to keep it at that width and make it responsive on smaller screens. You can adjust the max-width value to your liking or remove it.
So, the CSS would change to:
#image {
position: absolute;
display: block;
top: 20px;
left: 20px;
width: 1000px;
max-width: 85%; /* adjust as needed or remove */
height: auto;
}
Here's an example.
If I'm understanding correctly, you have a header container area where various images get populated, and sometimes the images are too big for the container and not looking good. (A screenshot would be helpful if my summary is wrong.)
The trick here is to set the image width to 100%, then set a max-width to either the image or the header container. (I picked 1200px for this example.) That ensures that your image will fill up all of the space, but not go over.
NOTE: this will cause images with widths smaller than 1200px to be stretched to fit, and may not look good either and would require some more coding to fix.
#image {
position: absolute;
display: block;
top: 20px;
left: 20px;
width: 100%;
max-width: 1200px;
}
<div id="wrapper">
<img src="https://upload.wikimedia.org/wikipedia/commons/c/cc/ESC_large_ISS022_ISS022-E-11387-edit_01.JPG" id="image">
</div>
However, if you're looking for a work-around for images that are smaller than 2000px wide, I'd suggest something like centering them with a colored background, or perhaps tiling them. Those solutions will be good for some content, and ugly for others - it depends what you images are like and how the site looks. But those are some ideas.
You may want to use the simple trick to automatically fit size with:
img { max-width: 1200px; height: auto;}
I guess 50px for height is not a must since you thought using "cover" in backround property. Also if you wish this sort of behavior from your image, you can add "object-fit: cover;".
Read more here: https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit
EDIT
You can also use that version of the "trick":
img { max-height: 100px; width: auto; }
Note: Using files that big for logo is not recomand. If you got access tto database you should consider save a copy to more light version with less pixels.

CSS: Make image height of viewport while keeping width 100% and cropping edges if wider than viewport

I want to create a responsive image that takes up the entire height off the viewport and scales as the viewport changes.
I know that I can set the height with this:
height: 100vmax;
However, I cannot understand how to get the image width to change and effectively crop it's edges off so that the image stays centred horizontally.
A great example of is Big Green Egg's website although they use a video and I want to use an image.
It's worth mentioning that I need to enter this code into a CMS page (Magento 2) so it will sit within a set of other DIVs.
Try to use "vh" and use text-align on the outer container to center the image:
body {
text-align: center;
}
img {
height: 100vh;
}
<img src="http://kingofwallpapers.com/sexy-girl-wallpapers/sexy-girl-wallpapers-002.jpg">
But I would recommend to use background-image instead, since it's a part of design, not a content:
* {
margin: 0;
}
.image {
position: absolute;
top: 50px;
bottom: 0;
left: 0;
right: 0;
background: #e0eaec url(http://eskipaper.com/images/mikako-zhang-5.jpg) no-repeat center center / auto 100%;
}
h1 {
line-height: 50px;
text-align: center;
}
<h1><header> goes here</h1>
<div class="image"></div>
I'd go very simple here, with a css solution based on adding only object-fit and an optional object-position, very useful when the main point for adjustment is not the center of the picture
html
<img src="https://images.unsplash.com/photo-1518453850752-056b15f0a4ea?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80">
css
img {
float: left;
width: 100%;
height: 100vh;
object-fit: cover;
object-position: 75% 75%;
}
Try to reduce the width of the picture in this JSFiddle: you will see that the focus will keep always around the dome. I suggest also to read this gem
By default, object-position: 50% 50% [i.e. the center of the picture] so in this case you don't need to specify it
NOTE - you can check their support on different browsers here

How to maintain proportion on resize of a layout with absolute positioned elements

I've been handed a bunch of pages to code up with weird irregular layouts. Below is an example of what I need to create.
The key points about this are;
The elements need to be positioned pixel perfect as per the mockups.
Upon window resize, all elements and the positions need to size down/up
proportionately.
The size of the container needs to resize proportionately also, because there will be more content under the layout.
Considering each element needs to have specific positioning, it's obvious to use absolute positioning. I also note that because the layout needs to stay proportionate, positioning needs to be done in percentages.
For images I can set the widths to be a percentage and height auto. And elements can be positioned with a percentage along the x axis.
But the problem arises when I need to position from the top.
If I declare an element to be say 20% from the top, this positioning won't change proportionately when I resize the page. Also, the containing block will need to have a declared height.
The only way I can see this working is with some javaScript trickery.
But this seems fussy for a seemingly simple layout. And it's not advisable to rely on javaScript to maintain a layout.
There must be a better solution, I've seen irregular layouts like this often.
I've looked into Flexbox, but I can't think of how it can help me in this situation.
How would you tackle this layout?
You can wrap everything in a wrapper that uses the "padding-bottom trick" to maintain its ratio based on its width. Because the height of the parent element is now dependent on the width of the document, all percentage values you give to top and bottom properties of child elements will be affected by the width of the page, instead of the height.
main {
position: relative;
width: 100%;
height: 0;
padding-bottom: 120%;
}
div {
background: red;
position: absolute;
}
.one {
width: 40%;
height: 40%;
top: 10%;
left: 40%;
}
.two {
width: 50%;
height: 20%;
top: 55%;
left: 15%;
}
.three {
width: 20%;
height: 30%;
top: 60%;
left: 70%;
}
<main>
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</main>
Try using this trick to scale your container proportionally
<div class="container">
<div class="container-inner-wrap">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
.container {
position: relative;
display: inline-block;
width: 75%; // Choose the width you want.
}
.container:after {
padding-top: [$height / $width * 100] %;
content: '';
display: block;
}
.container-inner-wrap {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
Where $height and $width are numbers - the value of the height and width you want your container to be. The real value you should put in there is what you get when you divide the ideal height by the width and multiply that by 100% (the unit is going to be %). What you get then is the aspect ratio of your container, and it will stay that size and shape no matter your browser size.
You can use that on all your boxes too, just make sure that you have that inner wrap that's absolutely positioned just inside. If I was building this layout, I'd use this trick for sure.
Here's an example of someone else using this: http://wellcaffeinated.net/articles/2012/12/10/very-simple-css-only-proportional-resizing-of-elements/

Make absolute positioned nested child the width of container

I'm essentially displaying a banner image on a page. At the base of that image is an overlay (the abs. pos. div) with a semi-transparent background image to make a "see through" effect. Everything is positioned properly and working fine except the overlay at a width of 100% expands outside of my container div. I've tried setting the overflow to hidden of the container div but that does not seem to work. My parent container has a position relative as well. This is responsive so the overlay with need to shrink and expand to the image width. Here's my code:
.hero-img-wrap {
position: relative;
margin-top: 35px;
padding-left: 15px;
padding-right: 15px;
}
.hero-img-wrap img {
width: 100%;
height: auto;
}
.hero-img-wrap .trans-overlay {
position: absolute;
bottom: 0;
z-index: 9;
height: 19px;
background-image: url('../images/semi_transparent_white.png');
width: 100%;
}
<div class="hero-img-wrap">
<img src="images/banner_image.jpg" alt="">
<div class="trans-overlay"></div>
</div>
I could pull this off with JQuery but I'd like to avoid that. For what it might be worth - this code is within a Bootstrap 3 column.
Since you've defined the height, why not a negative value
position: relative;
top: -19px;
Just a thought, heres a fiddle for ya
http://jsfiddle.net/g11yggap/
Try
Width:inherit;
On overlay div

CSS force image resize and keep aspect ratio

I am working with images, and I ran into a problem with aspect ratios.
<img src="big_image.jpg" width="900" height="600" alt="" />
As you can see, height and width are already specified. I added a CSS rule for images:
img {
max-width: 500px;
}
But for big_image.jpg, I receive width=500 and height=600. How do I set images to be re-sized, whilst keeping their aspect ratios.
img {
display: block;
max-width:230px;
max-height:95px;
width: auto;
height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="http://i.stack.imgur.com/aEEkn.png">
This will make image shrink if it's too big for specified area (as downside, it will not enlarge image).
Here's a solution:
object-fit: cover;
width: 100%;
height: 250px;
You can adjust the width and height to fit your needs, and the object-fit property will do the cropping for you.
More information about the possible values for the object-fit property and a compatibility table are available here: https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit
The solutions below will allow scaling up and scaling down of the image, depending on the parent box width.
All images have a parent container with a fixed width for demonstration purposes only. In production, this will be the width of the parent box.
Best Practice (2018):
This solution tells the browser to render the image with max available width and adjust the height as a percentage of that width.
.parent {
width: 100px;
}
img {
display: block;
width: 100%;
height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<div class="parent">
<img width="400" height="400" src="https://placehold.it/400x400">
</div>
Fancier Solution:
With the fancier solution, you'll be able to crop the image regardless of its size and add a background color to compensate for the cropping.
.parent {
width: 100px;
}
.container {
display: block;
width: 100%;
height: auto;
position: relative;
overflow: hidden;
padding: 34.37% 0 0 0; /* 34.37% = 100 / (w / h) = 100 / (640 / 220) */
}
.container img {
display: block;
max-width: 100%;
max-height: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<p>This image is originally 640x220, but should get resized by the CSS:</p>
<div class="parent">
<div class="container">
<img width="640" height="220" src="https://placehold.it/640x220">
</div>
</div>
For the line specifying padding, you need to calculate the aspect ratio of the image, for example:
640px (w) = 100%
220px (h) = ?
640/220 = 2.909
100/2.909 = 34.37%
So, top padding = 34.37%.
Very similar to some answers here, but in my case I had images that sometimes were taller, sometimes larger.
This style worked like a charm to make sure that all images use all available space, keep the ratio and not cuts:
.img {
object-fit: contain;
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
}
The background-size property is ie>=9 only, but if that is fine with you, you can use a div with background-image and set background-size: contain:
div.image{
background-image: url("your/url/here");
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
Now you can just set your div size to whatever you want and not only will the image keep its aspect ratio it will also be centralized both vertically and horizontally within the div. Just don't forget to set the sizes on the css since divs don't have the width/height attribute on the tag itself.
This approach is different than setecs answer, using this the image area will be constant and defined by you (leaving empty spaces either horizontally or vertically depending on the div size and image aspect ratio), while setecs answer will get you a box that exactly the size of the scaled image (without empty spaces).
Edit:
According to the MDN background-size documentation you can simulate the background-size property in IE8 using a proprietary filter declaration:
Though Internet Explorer 8 doesn't support the background-size property, it is possible to emulate some of its functionality using the non-standard -ms-filter function:
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='path_relative_to_the_HTML_file', sizingMethod='scale')";
Remove the "height" property.
<img src="big_image.jpg" width="900" alt=""/>
By specifying both you are changing the aspect ratio of the image. Just setting one will resize but preserve the aspect ratio.
Optionally, to restrict oversizings:
<img src="big_image.jpg" width="900" alt="" style="max-width:500px; height:auto; max-height:600px;"/>
Firefox 71+ (2019-12-03) and Chrome 79+ (2019-12-10) support internal mapping of the width and height HTML attributes of the IMG element to the new aspect-ratio CSS property (the property itself is not yet available for direct use).
The calculated aspect ratio is used to reserve space for the image until it is loaded, and as long as the calculated aspect ratio is equal to the actual aspect ratio of the image, page “jump” is prevented after loading the image.
For this to work, one of the two image dimensions must be overridden via CSS to the auto value:
IMG {max-width: 100%; height: auto; }
<img src="example.png" width="1280" height="720" alt="Example" />
In the example, the aspect ratio of 16:9 (1280:720) is maintained even if the image is not yet loaded and the effective image width is less than 1280 as a result of max-width: 100%.
See also the related Firefox bug 392261.
Here is a solution :
img {
width: 100%;
height: auto;
object-fit: cover;
}
This will make sure the image always covers the entire parent (scaling down and up) and keeps the same aspect ratio.
Just add this to your css, It will automaticly shrink and expand with keeping the original ratio.
img {
display: block;
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
}
This is mental. Use the scale-down property - it explains itself.
Inline styling:
<img src='/nic-cage.png' style={{ maxWidth: '50%', objectFit: 'scale-down' }} />
This will stop flex from stretching it. In this case, the image would go to 50% of the width of its parent container and the height would scale down to match.
Keep it simple.
Just replace the height attribute by the aspect-ratio attribute.
img {
max-width: 500px;
aspect-ratio: 900 / 600;
}
<img src="big_image.png" width="900"/>
The aspect-ratio attribute is not necessary, but prevent image layout shifts.
To maintain a responsive image while still enforcing the image to have a certain aspect ratio you can do the following:
HTML:
<div class="ratio2-1">
<img src="../image.png" alt="image">
</div>
And SCSS:
.ratio2-1 {
overflow: hidden;
position: relative;
&:before {
content: '';
display: block;
padding-top: 50%; // ratio 2:1
}
img {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
}
This can be used to enforce a certain aspect ratio, regardless of the size of the image that authors upload.
Thanks to #Kseso at http://codepen.io/Kseso/pen/bfdhg. Check this URL for more ratios and a working example.
Set the CSS class of your image container tag to image-class:
<div class="image-full"></div>
and add this you your CSS stylesheet.
.image-full {
background: url(...some image...) no-repeat;
background-size: cover;
background-position: center center;
}
I would suggest for a responsive approach the best practice would be using the Viewport units and min/max attributes as follows:
img{
display: block;
width: 12vw;
height:12vw;
max-width:100%;
min-width:100px;
min-height:100px;
object-fit:contain;
}
To force image that fit in a exact size, you don't need to write too many codes. It's so simple
img{
width: 200px;
height: auto;
object-fit: contain; /* Fit logo in the image size */
-o-object-fit: contain; /* Fit logo fro opera browser */
object-position: top; /* Set logo position */
-o-object-position: top; /* Logo position for opera browser */
}
<img src="http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png" alt="Logo">
https://jsfiddle.net/sot2qgj6/3/
Here is the answer if you want to put image with fixed percentage of width, but not fixed pixel of width.
And this will be useful when dealing with different size of screen.
The tricks are
Using padding-top to set the height from width.
Using position: absolute to put image in the padding space.
Using max-height and max-width to make sure the image will not over the parent element.
using display:block and margin: auto to center the image.
I've also comment most of the tricks inside the fiddle.
I also find some other ways to make this happen.
There will be no real image in html, so I personly perfer the top answer when I need "img" element in html.
simple css by using background
http://jsfiddle.net/4660s79h/2/
background-image with word on top
http://jsfiddle.net/4660s79h/1/
the concept to use position absolute is from here
http://www.w3schools.com/howto/howto_css_aspect_ratio.asp
You can use this:
img {
width: 500px;
height: 600px;
object-fit: contain;
position: relative;
top: 50%;
transform: translateY(-50%);
}
You can create a div like this:
<div class="image" style="background-image:url('/to/your/image')"></div>
And use this css to style it:
height: 100%;
width: 100%;
background-position: center center;
background-repeat: no-repeat;
background-size: contain; // this can also be cover
You can set the container to display: flex and align-items: center (other align-items values work too). Instead of align-items you can also set align-self on the image itself.
This will make image shrink if it's too big for specified area (as downside, it will not enlarge image).
The solution by setec is fine for "Shrink to Fit" in auto mode.
But, to optimally EXPAND to fit in 'auto' mode, you need to first put the received image into a temp id,
Check if it can be expanded in height or in width (depending upon its aspect ration v/s the aspect ratio of your display block),
$(".temp_image").attr("src","str.jpg" ).load(function() {
// callback to get actual size of received image
// define to expand image in Height
if(($(".temp_image").height() / $(".temp_image").width()) > display_aspect_ratio ) {
$(".image").css('height', max_height_of_box);
$(".image").css('width',' auto');
} else {
// define to expand image in Width
$(".image").css('width' ,max_width_of_box);
$(".image").css('height','auto');
}
//Finally put the image to Completely Fill the display area while maintaining aspect ratio.
$(".image").attr("src","str.jpg");
});
This approach is useful when received images are smaller than display box. You must save them on your server in Original Small size rather than their expanded version to fill your Bigger display Box to save on size and bandwidth.
You Can use:-
transform: scaleX(1.2);
to change the width without changing height.
And
transform: scaleY(1.2);
to change the height without changing width
You can use this on images and video tags in html and css. This does not change the aspect ration also.
you can use aspect-ratio property css
.my-image {
aspect-ratio: 1/1; // square
aspect-ratio: 16/9; // wide screen 1080p
aspect-ratio: 4/3;
aspect-ratio: 2/3;
}
img {
max-width: 80px; /* Also works with percentage value like 100% */
height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="https://i.stack.imgur.com/aEEkn.png">
<p>Let's say the author of the HTML deliberately wants
the height to be half the value of the width,
this CSS will ignore the HTML author's wishes, which may or may not be what you want:
</p>
<img width="400" height="200" src="https://i.stack.imgur.com/aEEkn.png">
How about using a pseudo element for vertical alignment? This less code is for a carousel but i guess it works on every fixed size container. It will keep the aspect ratio and insert #gray-dark bars on top/bottom or left/write for the shortest dimension. In the meanwhile the image is centered horizontally by the text-align and vertically by the pseudo element.
> li {
float: left;
overflow: hidden;
background-color: #gray-dark;
text-align: center;
> a img,
> img {
display: inline-block;
max-height: 100%;
max-width: 100%;
width: auto;
height: auto;
margin: auto;
text-align: center;
}
// Add pseudo element for vertical alignment of inline (img)
&:before {
content: "";
height: 100%;
display: inline-block;
vertical-align: middle;
}
}
Fullscreen presentation:
img[data-attribute] {height: 100vh;}
Keep in mind that if the view-port height is greater than the image the image will naturally degrade relative to the difference.
If the application can have an image of any aspect ratio or resolution then you can manage height and width as in this link.
This uses Javascript and HTML
https://stackoverflow.com/a/65090175/13338731

Resources