Как я могу удалить невидимую часть `clip-path`? - PullRequest
1 голос
/ 22 марта 2019

Я бы хотел вырезать изображения разного размера на высоте 50% каждое.

Итак, я подумал об использовании метода inset свойства clip-path. Но в этом свойстве вырезанное пространство остается высотой.

.container {
  display: flex;
  align-items: start;
}

.img {
  flex: 1;
  background: #900;
}

.img+.img {
  margin-left: 5px;
}

img {
  max-width: 100%;
  width: 100%;
  clip-path: inset(0 0 45% 0);
}
<div class="container">
  <div class="img">
    <img src="https://via.placeholder.com/300x550/009/fff.png" alt>
  </div>
  <div class="img">
    <img src="https://via.placeholder.com/200x200/090/fff.png" alt>
  </div>
  <div class="img">
    <img src="https://via.placeholder.com/600x150/09f/fff.png" alt>
  </div>
</div>

Поэтому я использовал overflow: hidden и height для редактирования исходного кода следующим образом:

.container {
  display: flex;
  align-items: start;
  height: 100vh;
}

.img {
  flex: 1;
  background: #900;
  height: 45%;
  overflow: hidden;
}

.img+.img {
  margin-left: 5px;
}

img {
  max-width: 100%;
  width: 100%;
}
<div class="container">
  <div class="img">
    <img src="https://via.placeholder.com/300x550/009/fff.png" alt>
  </div>
  <div class="img">
    <img src="https://via.placeholder.com/200x200/090/fff.png" alt>
  </div>
  <div class="img">
    <img src="https://via.placeholder.com/600x150/09f/fff.png" alt>
  </div>
</div>

Но это будет 45% высоты родительского контейнера, а не 45% высоты изображения.

Почему это поведение? И как мне вырезать 50% высоты каждого изображения и избавиться от лишнего пространства?

Ответы [ 2 ]

1 голос
/ 22 марта 2019

Высота в процентах относительно родительского элемента, и в этом случае вы сталкиваетесь со сложным поведением, где 45% - это высота самого высокого изображения, определяющего родительскую высоту.

Одна идея для получениявам нужно рассмотреть масштабирование, когда вы увеличиваете изображение в два раза, а контейнер уменьшаете в два раза:

.container {
  display: flex;
  align-items: start;
  height: 100vh;
}

.img {
  flex: 1;
  background: #900;
  overflow: hidden;
  transform:scaleY(0.5);
  transform-origin:top;
}

.img+.img {
  margin-left: 5px;
}

img {
  max-width: 100%;
  width: 100%;
  transform:scaleY(2);
  transform-origin:top;
}
<div class="container">
  <div class="img">
    <img src="https://via.placeholder.com/300x550/009/fff.png" alt>
  </div>
  <div class="img">
    <img src="https://via.placeholder.com/200x200/090/fff.png" alt>
  </div>
  <div class="img">
    <img src="https://via.placeholder.com/600x150/09f/fff.png" alt>
  </div>
</div>
0 голосов
/ 22 марта 2019

Интересный вызов.

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

Обратите внимание, что для ясности я переименовал то, что вы называли div.img s, в div.frame s.

.container {
  display: flex;
  align-items: start;
  height: 100vh;
}

.frame {
  flex: 1;
  background: lightgrey; /* set transparent to make frames invisible */
  position: relative;
}

img {
  display: block; /* default is inline-block, which adds extra space */
}

.frame + .frame {
  margin-left: 5px;
}

.frame > img {
  /* this image expands the .frame to fit full image size */
  height: auto;
  width: 100%;
  visibility: hidden;
}

.cropper {
  /* with parent .frame set to full image hight, 50% of .frame height is 50% of image hight */
  position: absolute;
  height: 50%;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
}

.cropper img {
  /* inside the cropper, display the normal image—it'll overflow at 50% of its height */
  width: 100%;
}
<div class="container">
  <div class="frame">
    <img src="https://via.placeholder.com/300x550/009/fff.png" alt>
    <div class="cropper">
      <img src="https://via.placeholder.com/300x550/009/fff.png" alt>
    </div>
  </div>
  <div class="frame">
    <img src="https://via.placeholder.com/200x200/090/fff.png" alt>
    <div class="cropper">
      <img src="https://via.placeholder.com/200x200/090/fff.png" alt>
    </div>
  </div>
  <div class="frame">
    <img src="https://via.placeholder.com/600x150/09f/fff.png" alt>
    <div class="cropper">
      <img src="https://via.placeholder.com/600x150/09f/fff.png" alt>
    </div>
  </div>
</div>

Он работает путем размещения полноразмерного невидимого изображения внутри каждого div.frame. Это «расширяет» каждый div.frame изнутри, чтобы соответствовать полной высоте изображения. Каждый div.frame, а затем также содержит абсолютную позицию div.cropper, установленную на 50% от высоты родительского контейнера. Поскольку наше невидимое изображение устанавливает для div.frame высоту изображения, это составляет 50% от высоты изображения, даже если оно масштабируется. Наконец, это .cropper снова содержит наше изображение. Поскольку .cropper имеет значение overflow: hidden, отображаются только верхние 50% изображения.

Я покрасил .frames в серый цвет, чтобы проиллюстрировать, что происходит. Если вы не хотите, чтобы .frame были видны, вы можете просто установить их background-color: transparent (или не указывать background-color - transparent по умолчанию).

Возможно, вам удастся сократить элементы <img> и добиться того же эффекта, используя background-image, но я пока еще не исказил этот метод, чтобы найти способ, который не не требует .frame s, чтобы оставаться на полную высоту, пока их содержимое «нарезано».

...