2 votes

Comment puis-je supprimer la partie non visible de `clip-path` ?

Je voudrais découper des images de taille variable à une hauteur de 50 % chacune.

J'ai donc pensé à utiliser la méthode d'insertion de l'élément clip-path propriété. Mais, dans cette propriété, l'espace découpé reste en hauteur.

.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>

J'ai donc utilisé overflow: hidden y height pour modifier le code source comme suit :

.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>

Mais, ce sera 45% de la hauteur du conteneur parent, et non 45% de la hauteur de l'image.

Pourquoi ce comportement ? Et comment puis-je couper 50% de la hauteur de chaque image et me débarrasser de l'espace supplémentaire ?

1voto

Temani Afif Points 69370

La hauteur du pourcentage est relative à l'élément parent et, dans ce cas, vous êtes confronté à un comportement complexe où l'élément 45% est la hauteur de l'image la plus haute qui définit la hauteur du parent.

Pour obtenir ce que vous voulez, vous pouvez envisager une mise à l'échelle qui consiste à augmenter deux fois l'échelle de l'image et à diminuer deux fois celle du conteneur :

.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>

0voto

Jacob Ford Points 393

Un défi intéressant.

Vous trouverez ci-dessous une méthode qui a l'apparence d'un recadrage de chaque image à sa seule hauteur supérieure, mais qui exige que les cadres contenant chaque image aient toujours leur pleine hauteur.

Notez que j'ai renommé ce que vous avez appelé div.img s à div.frame pour plus de clarté.

.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>

Il fonctionne en plaçant une pleine hauteur, invisible dans chaque div.frame . Cela "élargit" chaque div.frame de l'intérieur pour correspondre à la hauteur totale de l'image. Chaque div.frame entonces également contient une position absolue div.cropper qui est réglé à 50 % de la hauteur de son conteneur parent. Parce que notre image invisible a défini notre div.frame à la hauteur de l'image, ce est 50% de la hauteur de l'image, même si elle est mise à l'échelle. Enfin, cette .cropper contient à nouveau notre image. Parce que .cropper est réglé sur overflow: hidden Si vous avez choisi de ne pas afficher l'image, seuls les 50% supérieurs de l'image sont affichés.

J'ai coloré les .frames gris pour illustrer ce qui se passe. Si vous ne voulez pas que le .frame pour qu'ils soient visibles, il suffit de définir leur background-color: transparent (ou ne pas spécifier de background-color - transparent est la valeur par défaut).

Vous pouvez peut-être réduire <img> et obtenir le même effet en utilisant background-image mais je n'ai pas encore trouvé la bonne méthode pour trouver le moyen de n'a pas exiger le .frame de rester à pleine hauteur pendant que leur contenu est "haché".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X