{
  "$type": "site.standard.document",
  "content": {
    "$type": "at.markpub.markdown",
    "text": {
      "$type": "at.markpub.text",
      "markdown": "::: info\nThe method described in here is no longer the preferred method. Use the new [`aspect-ratio` property in CSS](#update-css-aspect-ratio).\n:::\n\nSometimes you just need a element to shrink or grow in height proportionally with the width. Some tags will naturally do this like the `img` tag or `video` tag, but sometimes you need this functionality on something like a `div`. For example, you might be lazy loading an image, but want to reserve the space of the image so content doesn't jump when the image loads in.\n\nWe can do this using a handy trick of padding.\n\n## The trick\nIf you give an element a top or bottom padding with a percent value that percent will be in relation to width of the elements parent. Let's take a look at an example to get a better idea of what that means.\n\nConsider the following:\n\n```html\n<style>\n  .parent {\n    width: 400px;\n  }\n  .child {\n    padding-bottom: 50%;\n    height: 0;\n    background-color: tomato;\n  }\n</style>\n<div class=\"parent\">\n  <div class=\"child\"></div>\n</div>\n```\n\nHere we have an element called `.parent` with a width of 400px and an element called `.child` with a bottom padding of 50%. When this renders the browser will resolve the bottom padding to 200px because that's what 50% of 400px (the width of the parent element) is. This results in the child element having an aspect ratio of 2:1. But you may be wondering why I set the height to 0 on the child element.\n\nBy default, a `div` will have a height to fit its contents; I want to make sure the height of the element is being only determined by my bottom padding and the quickest way to do that is to set the height to 0.\n\nNow that we've made a box with an aspect ratio, let's do something more practical like reserving space for a lazy-loading image.\n\n```html\n<style>\n  .post {\n    width: 400px;\n  }\n  .post .img-wrapper {\n    position: relative;\n    padding-bottom: calc(3 / 4 * 100%);\n    height: 0;\n  }\n  .post .img-wrapper img {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n  }\n</style>\n<article class=\"post\">\n  <div class=\"img-wrapper\">\n    <img data-src=\"/path/to/image.jpg\" alt=\"...\" />\n  </div>\n  <h3>Hello, World!</h3>\n  <p>Check out my super cool internet website for online enjoyment...</p>\n</article>\n```\n\nHere we have an bit of content with an image, title, and some body content. In this scenario, my image that I'm using has aspect ratio of 3:4 and I'm using those dimensions to define bottom padding percentage of the `.img-wrapper`.\n\n```css\n.post .img-wrapper {\n  padding-bottom: calc(3 / 4 * 100%);\n}\n```\n\nIn this case, I could have just set the bottom padding to 75%, but I find using the aspect ratio of the image in a `calc()` makes things very clear and readily update-able if my image aspect ratio ever needs to change. You'll also notice that we're absolutely positioning the `img` element; we have to do this because the `.img-wrapper` is being entirely filled with padding leaving no room for the `img` to sit in naturally. Absolutely positioning the `img` lets us place it in the top-left corner of the `.img-wrapper` and stretch it fill the available width and height.\n\nAll that is left to do is to lazy load in the image when it comes into the viewport. To do that, we can use an [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) which will be a topic for a future post.\n\n## Update: CSS aspect-ratio\nSince I originally wrote this CSS has gained `aspect-ratio` which will give a responsive element an aspect ratio. So you could simplify this to:\n\n```css\n.post img {\n\twidth: 100%;\n\taspect-ratio: 3 / 4;\n}\n```\n\nThats it! Nice and simple and far more clear to future maintainers what's going on.\n\n[Read more about `aspect-ratio` on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/aspect-ratio)."
    }
  },
  "description": "Sometimes you just need a element to shrink or grow in height proportionally with the width.",
  "path": "/posts/how-to-give-an-html-element-an-aspect-ratio",
  "publishedAt": "2019-07-27T00:00:00.000Z",
  "site": "at://did:plc:2lm4lab5fhnj6kaazrxopv37/site.standard.publication/self",
  "tags": [
    "html",
    "css"
  ],
  "title": "How to Give an HTML Element an Aspect Ratio"
}