Make responsive square div with a side length equal to parent's smallest side using only css

Viewed 24

Hello I want to make a square div with length of sides equal to smallest side of parent div. I know it is possible to do with js, but I need to use only css; in js it would look something like this:

parentDiv.width >= parentDiv.height 
 ? child.sideLength = parentDiv.height 
 : child.sideLength = parentDiv.width 

in css I wanted to use "@when" to compare parent sides or at least its orintation, but I wasn't able to refer a parent's width, height or orientation. I know css isn't really meant to have any logical operations, but I belive there should be a solution to achive what I want enter image description here

2 Answers

Give the child max width and height of 100% each and an aspect-ratio of 1 / 1.

Here's a simple example:

.parent1 {
  width: 100px;
  height: 200px;
  background: gray;
  position: relative;
}

.parent2 {
  width: 200px;
  height: 100px;
  background: gray;
  position: relative;
}

.child {
  background: red;
  max-width: 100%;
  max-height: 100%;
  aspect-ratio: 1 / 1;
}
<div class="parent1">
  <div class="child"></div>
</div>
<div class="parent2">
  <div class="child"></div>
</div>

One way with just CSS would be using container queries which is still new and being developed. https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries

.parent {
  /* Property of container queries */
  container-type: size;

  display: flex;
  width: 200px;
  height: 200px;

  background-color: #06f;

  resize: both;
  overflow: hidden;
}

.child {
  /* Unit of container queries for smallest size of parent */
  width: 100cqmin;

  height: 100%;
  max-height: 100px;

  margin: auto;

  background-color: #f00;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <link rel="icon" href="data:image/x-icon," type="image/x-icon">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
        <meta name="theme-color" content="#444">
        <meta name="color-scheme" content="dark">
        <style name="default-stylesheet">
            /*# sourceURL=default.css*/
            @charset "UTF-8";

            :root {
                box-sizing: border-box;
            }

            *:not(:root),
            *::before,
            *::after {
                box-sizing: inherit;
            }

            :where(:not(:defined)) {
                display: block;
            }


            /* Remove all styles */
            :where(a, button) {
                all: unset;
            }


            /* Normalize background-image */
            * {
                background-repeat: no-repeat;
            }


            /*
            Avoid autocalculation of `min-width` and `min-height` properties
            of flex/grid items based on the intrinsic size of its content
            */
            * {
                min-width: 0;
                min-height: 0;
            }

            /* Normalize flex-items behavior */
            * {
                flex-shrink: 0;
            }


            :root {
                --fit-content: fit-content;
            }

            @supports (width: -moz-fit-content) {
                :root {
                    --fit-content: -moz-fit-content;
                }
            }


            :root {
                background-color: #111;
                color: #fff;

                font-family: Arial;
                user-select: none;

                /* Remove highlight that appears on links or clickable elements on mobile */
                -webkit-tap-highlight-color: transparent;
            }

            * {
                user-select: inherit;
            }

            html,
            body {
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;

                overflow: hidden;
            }

            body,
            #app {
                background-color: inherit;
            }

            #app,
            #app-content {
                position: relative;
                width: 100%;
                height: 100%;
            }

            #app-content {
                padding: 1rem;

                overflow: auto;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div id="app-content">
                <div class="parent">
                    <div class="child"></div>
                </div>
            </div>
        </div>
    </body>
</html>

Related