Search code examples
htmlcssresponsive-designheightcss-variables

How to set default height of an HTML element and let it adjust to a fixed container height with CSS only


Suppose I'm developing a reusable component, rendered as an HTML element. It can be rendered by anybody in some container. I don't know the styles of the container in advance: it could have a fixed height, or no defined height at all (in which case the container is flexible adjusts to its content).

In other words, my element should be flexible when the container is fixed, and it should be fixed when the container is flexible.

I want my component to look nice in both cases. Basically, the requirements are:

  1. When the container has a fixed height, my element should adjust to it, as if it had height: 100%.
  2. When the container has no fixed height, my element should take the lead and render with some default height, as if it had its own fixed height.
  3. I do not control the styles of the outer container. I only control the inner element, which anybody can render where they want.
  4. I want to do it using only CSS, without JS.

I found some solutions that suggest using min-height to set the default height. But it won't work, because when the container has fixed height, I want my element to adjust to it, even if it will be smaller than the default.

Default height means neither minimal nor maximal height - it's just some reasonable default value. It can be static or provided from outside as a CSS variable - doesn't matter.


Solution

  • Basic Solution

    Let's say the component element has class "my-element". The following CSS should do the job:

    .my-element {
      height: 500px;
      min-height: 100%;
      max-height: 100%;
    }
    

    Here is how it works...

    A. When the container element has no fixed height (e.g. height: auto).

    The element will have height of 500px. The percentage value of min-height and max-height will be ignored. That's because relative height in CSS works only within containers with fixed height [1].

    B. When the container element has fixed height (e.g. height: 400px).

    The element will have the same height as the container. The min-height and max-height properties will overrule the height property so it will be basically ignored.

    Extended Solution

    We can extend this solution to have more control over the element from the outside via CSS variables, and to be able to provide fixed min/max height:

    .my-element {
      --my-min-height: var(--min-height, 100px);
      --my-max-height: var(--max-height, 1000px);
      height: var(--default-height, 500px);
      min-height: max(100%, --my-min-height); /* stretch to 100% but not less than --my-min-height */
      max-height: min(100%, --my-max-height); /* shrink to 100% but not more than --my-max-height */
    }
    

    This achieves the best flexibility:

    1. When rendered in a flexible container (without fixed height), this element will have a default height of 500px, which can be overwritten via --default-height variable.
    2. When rendered in a fixed-height container, this element will adjust to its height, but it won't become smaller than 100px or bigger than 1000px in height (both values can be overwritten via --min-height and --max-height variables accordingly).

    [1] Percentage Height HTML 5/CSS