htmlcssrotationimage-rotation

How adjust content width, height when rotate the block in css


There are many solutions on the Internet, but all of them are either crutches or do not work correctly. Perhaps there is a way to stretch the element in width and adjust the height when rotating more correct in 2023?

Below is the code and the problem that occurs. You can see that the block with the image extends beyond the wrapper and is not stretched wide enough.

enter image description here

.wrapper {
  border: 2px solid grey;
  display: flex;
  align-items: center;
  padding: 10px;
  height: 140px;
  width: 300px;
}


.left {
  flex-grow: 1;
  height: 100%;
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  border: 2px solid red;
}

.imgwrapper {
  border: 2px solid green;
  width: 70px;
  height: 100%;
  transform-origin: top left;
  transform: rotate(-90deg) translate(-100%);
}

img {
  width: 100%;
  height: 100%;
}
<div class=wrapper>
  <div class="left">
    <div class="lefttop">Top text</div>
    <div class="leftbottom">Bottom text</div>
  </div>
  <div class="imgwrapper">
    <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/EAN8.svg/1200px-EAN8.svg.png" alt="">
  </div>
</div>

Expected result: It should be something like this ( but of course wrapper width and height can be different ): enter image description here

Update: Since I generated this barcode by my own in real app, I suppose it's better to add numbers as another component with absolute, in order to save quality


Solution

  • CSS transforms don't introduce layout shifts – actually a good concept.

    As a workaround you can insert your image in an inlined <svg>.

    .wrapper {
      border: 2px solid grey;
      display: flex;
      align-items: center;
      padding: 10px;
      height: 140px;
      width: 300px;
    }
    
    .left {
      flex-grow: 1;
      height: 100%;
      display: flex;
      justify-content: space-between;
      flex-direction: column;
      border: 2px solid red;
    }
    
    .imgwrapper {
      width: 70px;
      height: 100%;
      transform-origin: top left;
    }
    <div class=wrapper>
      <div class="left">
        <div class="lefttop">Top text</div>
        <div class="leftbottom">Bottom text</div>
      </div>
      <div class="imgwrapper">
        <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
          <title>EAN</title>
           <image preserveAspectRatio="none" transform="rotate(-90)" transform-origin="50% 50%"  href="https://upload.wikimedia.org/wikipedia/commons/6/6d/Hitman_barcode.svg" width="100" height="100" />
        </svg>
      </div>
    </div>

    Basically we're creating a svg with a square (1/1) aspect ratio and rotate the <image> element with svg transforms.

    By setting a viewBox and preserveAspectRatio="none" (both for the parent svg and the image element) we can now squeeze the svg to fit the outer HTML div.