32

I would like to do the next trick in my css file so that (height = width) without setting pixels. I want to do this so whatever the resolution of the browser is, to have same values on these two dimensions.

#test{
    height: 100%;
    width: (same as height);
}

I prefer to do it with css and not javascript.

Thank you in advance.

Huangism
  • 16,278
  • 7
  • 48
  • 74
giorgos
  • 1,771
  • 4
  • 15
  • 14
  • Possible duplicate of this question: http://stackoverflow.com/questions/5445491/height-equal-to-dynamic-width-css-fluid-layout –  Feb 15 '14 at 15:58
  • 6
    @dpwivagg I don't think so. The OP wants `width: same as height` not `height: same as width`. – Hashem Qolami Feb 15 '14 at 16:00
  • You cannot reference other css statements with css. You could use less css which would allow you to do this. http://lesscss.org/ – Calvin Feb 15 '14 at 16:00
  • @Hashem Qolami, I have tried out to do it with jquery but the problem is that it does not work in all resolutions of smartphones. – giorgos Feb 15 '14 at 16:11

4 Answers4

47

This is my way

  aspect-ratio: 1 / 1;
  height: 100%;

Example:

.my-container {
  width: 100%;
  height: 150px;
  background: black;
  padding: 20px
}

.my-element {
  background: #fff;
  aspect-ratio: 1 / 1;
  height: 100%;
}
<div class="my-container">
  <div class="my-element">Height = Width</div>
</div>
Paulo Rosa
  • 606
  • 1
  • 5
  • 8
  • 1
    Fantastic! But can we use it? https://caniuse.com/mdn-css_properties_aspect-ratio - current support is about 70%, basically Safari doesn't implement it yet. If you use this, your site will break on iPhones and on Safari. ‍♂️ – Edward Sep 16 '21 at 09:47
  • 2
    100 million upvotes ... Safari now supports this ... thanks ... this should be top answer – danday74 Oct 02 '21 at 21:57
12

The only CSS way of doing this at the moment (AFAIK) is using viewport relates values (vh / vw )

Support is not great at the moment: http://caniuse.com/viewport-units but here is a quick demo

JSFiddle

CSS

.box {
    background-color: #00f;
    width: 50vw;
    height:50vw;
}

The box is responsive but will always remain square.

Pure % values will not work as height:100% does not equal width:100% as they refer to different things being the relevant dimensions of the parent.

Paulie_D
  • 107,962
  • 13
  • 142
  • 161
  • I think that this is what I really want..I will try it. Thank you – giorgos Feb 15 '14 at 16:57
  • Any idea how to position such `.box` element within its parent so it is centered both horizontally and vertically wise? – Michal Hosala Oct 01 '15 at 18:06
  • There's plenty of answers to that on SO. Just search for a while. – Paulie_D Oct 01 '15 at 18:20
  • Sorry, I had a bug in my code thanks to which my favorite `margin: auto; position: absolute; top, bottom, right, left: 0;` solution was not working, hence the question - I was blaming `vw` for it. – Michal Hosala Oct 02 '15 at 00:06
  • 1
    @Paulie_D - there are not "plenty of answers".. for this question. and this solution is not correct since it does not answer the title but rather answers a very specific scenario. I came here to seek an answer for title and got nothing :/ – vsync Jun 05 '17 at 15:58
9

Another options is to make aspect ratio using img element behavior

Here i use svg image and inline it with data url to make it simpler

To describe desired aspect ratio you can use viewBox svg attribute viewBox='0 0 width-ratio height-ratio'

Examples:

html,
body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
        "Ubuntu", "Cantarell", "Fira Sans",
        "Droid Sans", "Helvetica Neue", sans-serif;
    margin: 0;
    padding: 0;
}
body {
    margin: 1rem;
}

.row {
  padding: 8px 0px;
}

.block {
  display: inline-block;
  vertical-align: top;
  position: relative;
  margin-left: 8px;
  margin-right: 8px;
}

.block-content {
  position: absolute; 
  top: 0; 
  left: 0; 
  right: 0; 
  bottom: 0; 
  display: flex; 
  justify-content: center; 
  align-items: center;
}

.ratio--width-to-height {
  height: 100%; 
  width: auto;
}

.ratio--height-to-width {
  height: auto; 
  width: 100%;
}
<h1>
  Block aspect ratio with svg image
</h1>

<h2>
  width to height
</h2>

<div class="row">   
  <div class="block" style="background: lime; height: 120px;">
    <img class="ratio--width-to-height" 
    src="data:image/svg+xml;utf8,&lt;svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'&gt;&lt;/svg&gt;">
    <div class="block-content">1 : 1</div>
  </div>

  <div class="block" style="background: cyan; height: 120px;">
    <img class="ratio--width-to-height" 
    src="data:image/svg+xml;utf8,&lt;svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2 1'&gt;&lt;/svg&gt;">
    <div class="block-content">2 : 1</div>
  </div>
  
  <div class="block" style="background: orange; height: 120px;">
    <img class="ratio--width-to-height" 
    src="data:image/svg+xml;utf8,&lt;svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1.25'&gt;&lt;/svg&gt;">
    <div class="block-content">1 : 1.25</div>
  </div>
</div>

<h2>
  height to width
</h2>

<div class="row">   
  <div class="block" style="background: lime; width: 120px;">
    <img class="ratio--height-to-width" 
    src="data:image/svg+xml;utf8,&lt;svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'&gt;&lt;/svg&gt;">
    <div class="block-content">1 : 1</div>
  </div>

  <div class="block" style="background: cyan; width: 120px;">
    <img class="ratio--height-to-width" 
    src="data:image/svg+xml;utf8,&lt;svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2 1'&gt;&lt;/svg&gt;">
    <div class="block-content">2 : 1</div>
  </div>
  
  <div class="block" style="background: orange; width: 120px;">
    <img class="ratio--height-to-width" 
    src="data:image/svg+xml;utf8,&lt;svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1.25'&gt;&lt;/svg&gt;">
    <div class="block-content">1 : 1.25</div>
  </div>
</div>

Same example on codepen https://codepen.io/forceuser/pen/MMWBBx

ForceUser
  • 1,129
  • 1
  • 15
  • 23
  • Please clarify usage of "html," I could't find it on W3School or any other documentation – vikramvi Jul 09 '20 at 10:34
  • 3
    For anyone who came here because of the question title, this is the answer you are looking for. You use a child image tag with a 1:1 ratio and make the width of the parent auto. For the people who post "possible duplicate" out of ignorance, it is not a duplicate because the percentage padding trick goes on the width of the parent and not the height. So it only works if you are trying to make the height match the width, not the other way around – DanceSC May 10 '21 at 18:53
  • The aspect-ratio property is technically the best way, but it's supported only in recent versions of some browsers. This one is the best for now. – SRCP Dec 12 '21 at 21:58
-3

max-width / max-height worked for me:

An image of definite size is set in a div (.box).

.parent {
       position: absolute;
}

.box {
    width: 100%;
    height: 100%;
}

.box img {
   max-width: 100%;
   max-height: 100%;
}