Создание маски для всех браузеров с использованием css-преобразования, возникающие проблемы с позиционированием

#html #css #css-position #css-transforms

#HTML #css #css-position #css-преобразования

Вопрос:

Мне нужно создать маску для наложения изображения во всех браузерах на основе vh (нет clip-path )

Я использую div с вращательным преобразованием в качестве маски, а затем с внутренним изменением поворота.

Проблема, с которой я сталкиваюсь, заключается в том, что содержимое внутри внутреннего не позиционируется правильно. Изображение должно быть выровнено по верхнему левому краю внутреннего контейнера.

Я пытался:

  • позиционирование с верхним и левым значениями без эффекта.
  • Использование преобразования для перемещения внутреннего контейнера работает, но я не могу найти, как вычисляются требуемые значения.

https://jsfiddle.net/owfgLnv7/5/

 .container {
  width: 70vh;
  height: 100vh;
  background-color: blue;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
}

.tri {
  position: absolute;
  width: 70vh;
  height: 70vh;
  transform: rotate(45deg);
  top: calc((100vh - 70vh) / 2);
  transform-origin: center center;
  background-color: transparent;
  z-index: 2;
  overflow: hidden;
}

.reset-tri {
  position: relative;
  z-index: 1;
  transform: rotate(-45deg);
  transform-origin: center center;
}

.inner-container {
  background: black;
}

  

Необходимо настроить изображение так, чтобы оно было выровнено по верхнему левому краю и нормально текло

Комментарии:

1. Если вы перейдете по ссылке, вы увидите, что изображение не выровнено внутри ромба в верхнем левом углу

2. Изображение внутри ромба должно быть выровнено по верхнему левому краю, а не по какой-либо произвольной точке в пространстве

3. Ссылка такая, какая она есть СЕЙЧАС … не такая, как она должна выглядеть.

4. Вы продолжаете повторять одно и то же. ПОКАЖИТЕ нам, как это должно выглядеть.

5. ibb.co/VvB7DMh Розовый — Изображение черное — внутренний синий — трехконтейнерный- Темно-фиолетовый

Ответ №1:

В принципе, когда элементы преобразуются (здесь поворачиваются), они выводятся из потока — поэтому размеры не будут вести себя так, как это происходит, когда вы этого не делаете.

Один из подходов заключается в использовании простой математики:

  • если вы повернете квадрат на 45 градусов (здесь у вас квадрат 70vh) со стороной a , то диагональ будет √2 * a ~ 1.414 * a ,
  • поскольку transform-origin здесь center , это означает, что у вас есть ширина или высота переполнения, равные (1.414 * a - a) / 2 или (1.414 - 1) * a / 2 .
  • аналогичный аргумент может быть указан для ширины container , которая будет иметь ширину, равную width: calc(1.414 * 70vh)

Смотрите демонстрацию ниже:

 body {
  margin: 0;
}

.page {
  width: 100vw;
  height: 100vh;
  background: grey;
}

.container {
  width: calc(1.414 * 70vh); /* changed */
  height: 100vh;
  background-color: blue;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
}

.tri {
  position: absolute;
  width: 70vh;
  height: 70vh;
  transform: rotate(45deg);
  top: calc(0.414 * 70vh / 2); /* changed */
  left: calc(0.414 * 70vh / 2); /* added */
  transform-origin: center center;
  background-color: transparent;
  z-index: 2;
  overflow: hidden;
}

.reset-tri {
  position: relative;
  z-index: 1;
  transform: rotate(-45deg);
  transform-origin: center center;
}

.inner-container {
  background: black;
}  
 <div class="page">
  <div class="container">
    <div class="tri">
      <div class="reset-tri">
        <div class="inner-container">
          <img src="https://openclipart.org/download/230732/360sj3.svg" />
        </div>
      </div>
    </div>
  </div>
</div>  


Использование фонового изображения

Для почти идеальной маскировки вы можете:

  • переместите image в background-image reset-tri контейнер и

  • добавьте scale(1.414) преобразование, чтобы точно заполнить исходный не преобразованный tri контейнер.

Смотрите демонстрацию ниже:

 body {
  margin: 0;
}

.page {
  width: 100vw;
  height: 100vh;
  background: grey;
}

.container {
  width: calc(1.414 * 70vh); /* changed */
  height: 100vh;
  background-color: blue;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
}

.tri {
  position: absolute;
  width: 70vh;
  height: 70vh;
  transform: rotate(45deg);
  top: calc(0.414 * 70vh / 2); /* changed */
  left: calc(0.414 * 70vh / 2); /* added */
  transform-origin: center center;
  background-color: transparent;
  z-index: 2;
  overflow: hidden;
}

.reset-tri {
  position: relative;
  z-index: 1;
  transform: rotate(-45deg) scale(1.414); /* scale by √2 */
  transform-origin: center center;
  width: 70vh;
  height: 70vh;
  /* use a bacground image */
  background-size: cover;
  background-image: url("https://openclipart.org/download/230732/360sj3.svg");
}  
 <div class="page">
  <div class="container">
    <div class="tri">
      <div class="reset-tri"></div>
    </div>
  </div>
</div>  


Использование элемента изображения

Для почти идеальной маскировки без использования background-image вы можете вернуться к предыдущей разметке и добавить object-fit: cover к img элементу, который заполняет размеры его оболочки, inner-container — см. демонстрацию ниже:

 body {
  margin: 0;
}

.page {
  width: 100vw;
  height: 100vh;
  background: grey;
}

.container {
  width: calc(1.414 * 70vh); /* changed */
  height: 100vh;
  background-color: blue;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
}

.tri {
  position: absolute;
  width: 70vh;
  height: 70vh;
  transform: rotate(45deg);
  top: calc(0.414 * 70vh / 2); /* changed */
  left: calc(0.414 * 70vh / 2); /* added */
  transform-origin: center center;
  background-color: transparent;
  z-index: 2;
  overflow: hidden;
}

.reset-tri {
  position: relative;
  z-index: 1;
  transform: rotate(-45deg) scale(1.414); /* scale by √2 */
  transform-origin: center center;
  width: 70vh;
  height: 70vh;
}

.inner-container {
  height: 100%; /* fill the parent wrapper */
}

.inner-container > img {
  width: 100%;
  height: 100%;
  object-fit: cover; /* the image fills the parent container */
}  
 <div class="page">
  <div class="container">
    <div class="tri">
      <div class="reset-tri">
        <div class="inner-container">
          <img src="https://openclipart.org/download/230732/360sj3.svg" />
        </div>
      </div>
    </div>
  </div>
</div>  

Комментарии:

1. Спасибо за исчерпывающий ответ. Однако здесь по-прежнему возникает проблема с позиционированием элемента img. Он не совпадает с верхним левым углом родительского элемента

2. Спасибо за решение для фонового изображения. Однако я все еще не вижу, как расположить элементы внутри этого

3. @jwtea извините за поздний ответ, я думал, что уже обновил ответ вчера… добавлены опции как background-image , так и image element выше…

4. Большое вам спасибо, куккуз. Мне удалось избежать использования object-fit для работы в IE со следующим спасибо за вашу помощь! jsfiddle.net/m3p2vacy/1