CSS: 100% width or height while keeping aspect ratio?
Asked Answered
C

17

229

Currently, with STYLE, I can use width: 100% and auto on the height (or vice versa), but I still can't constrain the image into a specific position, either being too wide or too tall, respectively.

Any ideas?

Chequered answered 20/9, 2010 at 12:42 Comment(1)
can you post a link or screenshot to show an example of the issue?Monopolize
C
159

If you only define one dimension on an image the image aspect ratio will always be preserved.

Is the issue that the image is bigger/taller than you prefer?

You could put it inside a DIV that is set to the maximum height/width that you want for the image, and then set overflow:hidden. That would crop anything beyond what you want.

If an image is 100% wide and height:auto and you think it's too tall, that is specifically because the aspect ratio is preserved. You'll need to crop, or to change the aspect ratio.

Please provide some more information about what you're specifically trying to accomplish and I'll try to help more!

--- EDIT BASED ON FEEDBACK ---

Are you familiar with the max-width and max-height properties? You could always set those instead. If you don't set any minimum and you set a max height and width then your image will not be distorted (aspect ratio will be preserved) and it will not be any larger than whichever dimension is longest and hits its max.

Cookshop answered 20/9, 2010 at 13:20 Comment(5)
if the image is taller than it is wide, I would use height=100% and width=auto, if the image is wider than it is tall, I would use width=100%, height=auto. i simply never know what the case is? cropping by max height/width would work- but if there's a way not to- i'd rather use that...Chequered
Well, are you designing a fluid or fixed-width layout? If you're in a fixed-width layout you can always set your width to 100% and the image will scale appropriately, but it may be very tall. Are you trying to position an image in a block of text, or use it as a banner, or as a background? If you could show the page where you're planning to use it or describe the context I could help you more. See edits above as well.Cookshop
using max-height on my img allowed me to constrain images while keeping their aspect ratioDendriform
object-fit no use?Cordillera
object-fit may crop image and hide detailsBury
E
91

Some years later, looking for the same requirement, I found a CSS option using background-size.

It is supposed to work in modern browsers (IE9+).

<div id="container" style="background-image:url(myimage.png)">
</div>

And the style:

#container
{
  width:  100px; /*or 70%, or what you want*/
  height: 200px; /*or 70%, or what you want*/
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

The reference: http://www.w3schools.com/cssref/css3_pr_background-size.asp

And the demo: http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size

Elude answered 27/6, 2013 at 21:47 Comment(5)
the ideal solution, which sadly isn't supported by IE8 :(Jemma
This is the ideal solution, but if you do this in carousels, it causes the images to be blank for a second after each slide.Caesium
This was the best solution for me. Our stack: react + material UIMagdeburg
Switching from an img to CSS background-image worked for me but I used contain, not cover for background-size — otherwise I lost some of the image.Altheta
This won't distort the image at all, but you'll still need to explicitly set a width and height on the div element. The image keeps its aspect ratio, but the element itself won'tProjectile
V
71

Simple elegant working solution:

img {
  width: 600px;  /*width of parent container*/
  height: 350px; /*height of parent container*/
  object-fit: contain;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}
Vickers answered 26/3, 2016 at 0:35 Comment(7)
Thanks for reminding me about object-fit. Exactly what I needed.Rappee
This is an ideal solution, but unfortunately object-fit is not supported in any versions of IE nor Edge as of March 28th, 2017.Mittel
As of March 2019 this feature has 90% support - so this really should be considered the correct answer.Scratchboard
Also, notice that object-fit: contain and object-fit: cover dont like width like 100% - you should use concrete units like pxAylmer
I tried object-fit with max-width and max-height as used in other answers, but that didn't work. this works perfectly for random image sizes even with width and height 100%Brena
Note: object-fit will affect negatively scroll behavior. use background-size: cover insteadSpan
This works great! I have a range of vertical and horizontal images that are all slightly different sizes and this works really well.Sarcasm
S
68

By setting the CSS max-width property to 100%, an image will fill the width of it's parenting element, but won’t render larger than it's actual size, thus preserving resolution.

Setting the height property to auto maintains the aspect ratio of the image, using this technique allows static height to be overridden and enables the image to flex proportionally in all directions.

img {
    max-width: 100%;
    height: auto;      
}
Setter answered 15/1, 2013 at 17:33 Comment(2)
yet setting height to auto causes reflow when image is floatedIronlike
the problem is when in a screen mobile, is not full heightMandamandaean
H
32

Had the same issue. The problem for me was that the height property was also already defined elsewhere, fixed it like this:

.img{
    max-width: 100%;
    max-height: 100%;
    height: inherit !important;
}
Hyetology answered 26/9, 2014 at 18:9 Comment(2)
Exactly what I was looking for. Thanks a million dude.Squander
Perfect where image size can be smaller or larger than the parent div, and it will be resized into perfect center with maximum width OR maximum height. You do not have to use image as a background which will just overfill the parent if set to "cover".Leghorn
D
12

Simple solution:

min-height: 100%;
min-width: 100%;
width: auto;
height: auto;
margin: 0;
padding: 0;

By the way, if you want to center it in a parent div container, you can add those css properties:

position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

It should really work as expected :)

Deaver answered 11/1, 2016 at 23:47 Comment(3)
upvoted the first part. second part did not work for me... :(Castellano
Just one problem - if the image is larger than 100% of the container, it will spill out and will require scrollbars or cropping. Not sure, how to achieve the same and still limit the max size to the container. If setting max-width and height, it does not preserve aspect ratio anymore.Newfoundland
@Newfoundland I was having the same issue, container is small and fixed size. Width or height 100% messed with aspect ratio. Solution was to use object-fit: contain, but that doesn't work in IE11 only Edge as of 2020.Tabb
T
5

One of the answers includes the background-size: contain css statement which I like a lot because it is straightforward statement of what you want to do and the browser just does it.

Unfortunately sooner or later you are going to need to apply a shadow which unfortunately will not play well with background image solutions.

So let's say that you have a container which is responsive but it has well defined boundaries for min and max width and height.

.photo {
  max-width: 150px;
  min-width: 75px;
  max-height: 150px;
  min-height: 75px;
}

And the container has an img which must be aware of the pixels of the height of the container in order to avoid getting a very high image which overflows or is cropped.

The img should also define a max-width of 100% in order first to allow smaller widths to be rendered and secondly to be percentage based which makes it parametric.

.photo > img {
  max-width: 100%;
  max-height: 150px;
  -webkit-box-shadow: 0 0 13px 3px rgba(0,0,0,1);
  -moz-box-shadow:    0 0 13px 3px rgba(0,0,0,1);
  box-shadow:         0 0 13px 3px rgba(0,0,0,1);
}

Note that it has a nice shadow ;)

Enjoy a live example at this fiddle: http://jsfiddle.net/pligor/gx8qthqL/2/

Trefler answered 10/5, 2015 at 20:58 Comment(2)
Cheers - exactly what I was looking for.Outcast
Thanks for this solutions and jsdfiddle link. This actually worked for my react-image-gallery where I use both: images with bigger height and images with bigger width. :)Duodecillion
S
5

To attempt a width of 100% and force a maximum height without distorting the aspect ratio, you can add a max-height declaration combined with object-fit:contain.

width:100%;
max-height: 600px;
object-fit: contain;
Screak answered 22/6, 2023 at 7:57 Comment(0)
P
4

I use this for a rectangular container with height and width fixed, but with images of different sizes.

img {
  max-width: 95%;
  max-height: 15em;
  width: auto !important;
}
Parcheesi answered 12/8, 2015 at 15:36 Comment(0)
H
4

Nowadays one can use vw and vh units, which represent 1% of the viewport's width and height respectively.

https://css-tricks.com/fun-viewport-units/

So, for example:

img {
  max-width: 100vw;
  max-height: 100vh;
}

... will make the image as wide as tall as possible, maintaining aspect ratio, but without being wider or higher than 100% of the viewport.

Hymanhymen answered 30/9, 2019 at 15:8 Comment(0)
C
3

Its best to use auto on the dimension that should respect the aspect ratio. If you do not set the other property to auto, most browsers nowadays will assume that you want to respect the aspect ration, but not all of them (IE10 on windows phone 8 does not, for example)

width: 100%;
height: auto;
Crore answered 3/11, 2013 at 10:27 Comment(0)
D
2

This is a very straightforward solution that I came up with after following conca's link and looking at background size. It blows the image up and then fits it centered into the outer container w/o scaling it.

<style>
#cropcontainer
{
  width:  100%; 
  height: 100%; 
  background-size: 140%;
  background-position: center;
  background-repeat: no-repeat;
}
</style>

<div id="cropcontainer" style="background-image: url(yoururl); />
Diaghilev answered 12/8, 2013 at 19:51 Comment(2)
Good and smart solution! With the additional 40% you are compensate the aspect ratio. Thanks!Verbality
You could also just use background-size: contain; to fit the image into a background.Mittel
B
1

Not to jump into an old issue, but...

#container img {
      max-width:100%;
      height:auto !important;
}

Even though this is not proper as you use the !important override on the height, if you're using a CMS like WordPress that sets the height and width for you, this works well.

Brownstone answered 16/3, 2015 at 19:18 Comment(0)
C
0

Use JQuery or so, as CSS is a general misconception (the countless questions and discussions here about simple design goals show that).

It is not possible with CSS to do what you seem to wish: image shall have width of 100%, but if this width results in a height that is too large, a max-height shall apply - and of course the correct proportions shall be preserved.

Carrion answered 9/12, 2013 at 7:12 Comment(0)
P
0

The modern approach uses aspect-ratio.

If one has a parent with a well-defined size, then nesting aspect-ratio can be used to constrain to both the width and the height.

For example, if one has a fullscreen page, and wants a square chess-board in the middle of it, then this technique can be used.

/* Stay smol, not absolutely needed*/
.constrain-container {
  display: flex;
  height: 100%;
}

.constrain-height {
  display: flex;
  min-width: 0;
  width: auto;
  height: 100%;
  aspect-ratio: 1/1;
  margin: auto;
  
  background-color: green;
}

.constrain-width {
  display: flex;
  min-width: 0;
  width: 100%;
  height: auto;
  aspect-ratio: 1/1;
  margin: auto;
  
  background-color: blue;
}
<!-- Resizable container, usually this would be a parent container with a fixed width and height -->
<div style="border: 1px solid black; resize: both; min-height: 30px; min-width: 30px; overflow: auto; ">
<div class="constrain-container">
<div class="constrain-height">
    <div class="constrain-width">My beautiful blue content is right here: Lorem ipsum</div>
  </div>
</div>
</div>
Protectorate answered 1/2 at 19:41 Comment(0)
P
0

The simplest answer since 2023 is using the CSS container queries. These let you say "this element is a container" and then "use the width/height of the container".

.container {
  width: 100%;
  height: 100%;
  
  container-type: size;
}

.square {
  width: 100cqmin;
  height: 100cqmin;
  
  background: blue; /* for demo purposes */
}
<!-- Resizable container for demo -->
<div style="border: 1px solid black; resize: both; height: 80px; width: 300px; overflow: auto; ">

  <div class="container">
    <div class="square">
      My beautiful content is right here: Lorem ipsum
      <br>
      blabla
      <br>
      cats are cute
    </div>
  </div>
</div>
Protectorate answered 26/2 at 18:58 Comment(0)
T
-2

I think this is what your looking for, i was looking for it my self, but then i remembered it again befor i found the code.

background-repeat: repeat-x;
background-position: top;
background-size:auto;
background-attachment: fixed;

digital evolution is on its way.

Theodicy answered 12/7, 2014 at 18:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.