Search code examples
csshorizontal-alignment

Horizontally align a stretched image inside a div?


How can I horizontally align - at an arbitrary percentage - a stretched/scaled image inside a div?

See the html below. The image needs to be horizontally aligned inside the div, by an arbitrary percentage.
So, 0% = left, 50% = centered, 53% = almost centered, and 100% = right

// just a toggle script, not relevant to the question
const toggle = function() {
    const viewportElement = document.querySelector('.viewport');
    if (viewportElement.classList.contains('viewport--portrait')) {
        viewportElement.classList.remove('viewport--portrait')
    } else {
        viewportElement.classList.add('viewport--portrait')
    }
};
.viewport {
    position: relative;
    margin: 60px auto;
    overflow: hidden;
    width: 667px;
    height: 375px;

}
.viewport--portrait {
    width: 375px;
    height: 667px;
}

.btn_toggle {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1;
    padding: 10px 20px;
}

/* *** relevant styles below *** */

.container {
    position: relative;
    height: 100%;
    width: 100%;
    border: 1px solid blue;
}

.image-wrapper {
    position: absolute;
    left: 0;
    right: 0;
    width: 100%;
    height: 100%;
    /* ???? */
}

.image-wrapper img {
    height: 100%;
    width: auto;
    object-fit: cover;
}
<div class="viewport viewport--portrait">
    <div class="container">
        <div class="image-wrapper">
            <img src="https://i.imgur.com/nigSBoN.jpeg" width="1952" height="765" alt="Chocolate!">
        </div>
        <button class="btn_toggle" onclick="toggle();">Toggle</button>
    </div>
</div>

<div class="viewport">
    <div class="container">
        <div class="image-wrapper">
            <img src="chocolate.jpg" width="1952" height="765" alt="Chocolate!">
        </div>
    </div>
</div>

Is there a method to consistently horizontally align stretched images?


Solution

  • Use

      position: relative;
      left: var(--p);
      transform: translate(calc(-1*var( --p)));
    

    on the image element then simply adjust the variable to define the percentage:

    // just a toggle script, not relevant to the question
    const toggle = function() {
      const viewportElement = document.querySelector('.viewport');
      if (viewportElement.classList.contains('viewport--portrait')) {
        viewportElement.classList.remove('viewport--portrait')
      } else {
        viewportElement.classList.add('viewport--portrait')
      }
    };
    .viewport {
      position: relative;
      margin: 60px auto;
      overflow: hidden;
      width: 667px;
      height: 375px;
    }
    
    .viewport--portrait {
      width: 375px;
      height: 667px;
    }
    
    .btn_toggle {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      z-index: 1;
      padding: 10px 20px;
    }
    
    
    /* *** relevant styles below *** */
    
    .container {
      position: relative;
      height: 100%;
      width: 100%;
      border: 1px solid blue;
      box-sizing: border-box;
    }
    
    .image-wrapper {
      --p: 20%;
      position: absolute;
      left: 0;
      right: 0;
      width: 100%;
      height: 100%;
    }
    
    .image-wrapper img {
      height: 100%;
      width: auto;
      object-fit: cover;
      position: relative;
      left: var(--p);
      transform: translate(calc(-1*var( --p)));
    }
    <div class="viewport viewport--portrait">
      <div class="container">
        <div class="image-wrapper">
          <img src="https://i.imgur.com/nigSBoN.jpeg" width="1952" height="765" alt="Chocolate!">
        </div>
        <button class="btn_toggle" onclick="toggle();">Toggle</button>
      </div>
    </div>