Home > Software design >  Empty responsive square with sides equal to sibling's height inside a flexbox
Empty responsive square with sides equal to sibling's height inside a flexbox

Time:01-03

I have a flex container with two elements inside of it.

One is text inside of a div. Second is a box that should be a square.

  • Side of the square must be equal to the text's line-height (if text size changes, box should scale);
  • If text size changes, container's height should also change.
  • Box should stick to the right side of flex container (it does now).

What I have so far:

Current state

What I'm struggling to achieve:

Desired state

I have tried aspect-ratio CSS property, but it doesn't work without explicit height declaration. If I explicitly set height to 100%, box collapses vertically. Padding technique only for boxes with explicit width, thus not applicable. Thought about using font-size as height, but former not equal to line-height.

Looking for a CSS solution.

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  font-size: 22px;
}

.container {
  position: relative;
  left: 30%;
  top: 50px;
  width: 40%;
  border: 1px solid black;
  padding: 8px 24px;
  border-radius: 30px;
}

.task {
  display: flex;
  justify-content: space-between;
  border: 1px solid green;
}

.task-info {
  border: 1px solid blue;
}

.task-button {
  border: 1px solid red;
}
<div >
  <div >
    <div >
      Content
    </div>
    <div >
    </div>
  </div>
</div>

CodePudding user response:

If you just need a square on the right then this can be drawn as a pseudo element:

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  font-size: 22px;
}

.container {
  position: relative;
  left: 30%;
  top: 50px;
  width: 40%;
  border: 1px solid black;
  padding: 8px 24px;
  border-radius: 30px;
}

.task {
  display: flex;
  justify-content: space-between;
  border: 1px solid green;
  position: relative;
}

.task-info {
  border: 1px solid blue;
}

.task-info::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  border: 1px solid red;
  height: 100%;
  aspect-ratio: 1;
  z-index: -1;
}

.task-button {
  border: 1px solid transparent;
}
<div >
  <div >
    <div >
      Content
    </div>
  </div>
</div>

However, I guess you may want more than this - e.g. clickable. One way to achieve this would be to have the clicking on the whole content element - but it depends on exactly what is required functionally.

CodePudding user response:

You can use pseudo element to create that square:

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  font-size: 22px;
}

.container {
  position: relative;
  left: 30%;
  top: 50px;
  width: 40%;
  border: 1px solid black;
  padding: 8px 24px;
  border-radius: 30px;
}

.task {
  display: flex;
  justify-content: space-between;
  border: 1px solid green;
}

.task-info {
  border: 1px solid blue;
}

.task-button:before {
  content: "";
  display: block;
  height: 100%;
  box-sizing: border-box;
  aspect-ratio: 1;
  box-shadow: 0 0 0 1px inset red;
  transform: translate(-100%);
}
<div >
  <div >
    <div >
      Content
    </div>
    <div >
    </div>
  </div>
</div>

  • Related