web-dev-qa-db-fra.com

Flèche / triangle transparent en retrait

Je voudrais faire un flèche transparente sur une image. Ce triangle doit être en retrait dans un bloc semi-transparent et afficher l'image d'arrière-plan.

Sortie désirée:

transparent indented CSS triangle

.barShow {
  background-color: #000;
  opacity: 0.5;
}

.barShow:before {
  top: 0%;
  left: 50%;
  border: solid transparent;
  content: " ";
  height: 0;
  width: 0;
  position: absolute;
  pointer-events: none;
  border-top-color: #999;
  border-width: 20px;
  margin-left: -20px;
}
<div class="barShow"></div>

Flèche CSS transparente doit être transparent sans couleur.

46
user3003727

Il existe plusieurs approches pour faire une flèche transparente sur une image avec [~ # ~] css [~ # ~] =. Les deux que je vais décrire impliquent des pseudo-éléments pour minimiser le balisage et ont la même sortie. Vous pouvez également voir une approche SVG à la fin de cette réponse:

Transparent arrow over an image

L'effet transparent sur la partie noire autour de la flèche est fait avec rgba() couleurs qui permettent la transparence. Mais vous pouvez utiliser l'opacité sur les pseudo-éléments si vous préférez.


1. SkewX ()

Vous pouvez utiliser la propriété CSS3skewX() sur deux pseudo-éléments pour rendre la flèche transparente. Le principal atout de cette approche est que la flèche transparente peut être réactive mais elle vous permet également de mettre une bordure sur la forme noire et autour du bordel.

La réactivité de la forme est faite avec la propriété padding-bottom Pour maintenir son rapport d'aspect (cette technique est décrite ici ).

DÉMO

.wrap {
  position: relative;
  overflow: hidden;
  width: 70%;
  margin: 0 auto;
}
.wrap img {
  width: 100%;
  height: auto;
  display: block;
}
.arrow {
  position: absolute;
  bottom: 0;
  width: 100%;
  padding-bottom: 3%;
  background-color: rgba(0, 0, 0, 0.8);
}
.arrow:before,
.arrow:after {
  content: '';
  position: absolute;
  bottom: 100%;
  width: 50%;
  padding-bottom: inherit;
  background-color: inherit;
}
.arrow:before {
  right: 50%;
  -ms-transform-Origin: 100% 100%;
  -webkit-transform-Origin: 100% 100%;
  transform-Origin: 100% 100%;
  -ms-transform: skewX(45deg);
  -webkit-transform: skewX(45deg);
  transform: skewX(45deg);
}
.arrow:after {
  left: 50%;
  -ms-transform-Origin: 0 100%;
  -webkit-transform-Origin: 0 100%;
  transform-Origin: 0 100%;
  -ms-transform: skewX(-45deg);
  -webkit-transform: skewX(-45deg);
  transform: skewX(-45deg);
}
<div class="wrap">
  <img src="https://farm8.staticflickr.com/7187/6895047173_d4b1a0d798.jpg" />
  <div class="arrow"></div>
</div>

La prise en charge du navigateur pour la propriété transform : skew() est IE9 + ( voir canIuse ).

2. Frontière

L'atout de cette technique est le support du navigateur, donc si vous avez besoin du support IE8, celui-ci est pour vous. L'inconvénient est que la forme ne peut pas répondre car la bordure ne peut pas utiliser des largeurs%.

DÉMO

.wrap {
  position: relative;
  overflow: hidden;
  width: 70%;
  margin: 0 auto;
}
.wrap img {
  width: 100%;
  height: auto;
  display: block;
}
.arrow {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 20px;
  background-color: rgba(0, 0, 0, 0.8);
}
.arrow:before,
.arrow:after {
  content: '';
  position: absolute;
  bottom: 100%;
  width: 50%;
  box-sizing: border-box;
}
.arrow:before {
  right: 50%;
  border-bottom: 20px solid rgba(0, 0, 0, 0.8);
  border-right: 20px solid transparent;
}
.arrow:after {
  left: 50%;
  border-bottom: 20px solid rgba(0, 0, 0, 0.8);
  border-left: 20px solid transparent;
}
<div class="wrap">
  <img src="https://farm8.staticflickr.com/7187/6895047173_d4b1a0d798.jpg" />
  <div class="arrow"></div>
</div>

3. Jouez avec!

Exemple: si vous pouvez changer la couleur transparente noire en la même que votre couleur d'arrière-plan (blanc ici), vous pouvez créer un triangle/flèche transparent avec la même image d'arrière-plan que le bloc:

transparetn arrow with a see through image

DÉMO

.wrap {
    position: relative;
    overflow: hidden;
    width: 50%;
    margin: 0 auto;
    background-color:#fff;
}
.wrap img {
    width: 100%;
    height: auto;
    display: block;
}
.wrap:before, .wrap:after {
    content:'';
    position: absolute;
    bottom: 0;
    width: 50%;
    background-color: inherit;
    padding-bottom:3%;
}
.wrap:before {
    right: 50%;
    -ms-transform-Origin: 100% 100%;
    -webkit-transform-Origin: 100% 100%;
    transform-Origin: 100% 100%;
    -ms-transform: skewX(45deg);
    -webkit-transform: skewX(45deg);
    transform: skewX(45deg);
}
.wrap:after {
    left: 50%;
    -ms-transform-Origin: 0 100%;
    -webkit-transform-Origin: 0 100%;
    transform-Origin: 0 100%;
    -ms-transform: skewX(-45deg);
    -webkit-transform: skewX(-45deg);
    transform: skewX(-45deg);
}
<div class="wrap">
    <img src="https://farm8.staticflickr.com/7187/6895047173_d4b1a0d798.jpg" />
</div>

4. Infobulle avec un triangle sur une image.

Si vous devez utiliser cette forme sur une autre image , un dégradé d'arrière-plan ou toute autre couleur non unie, vous devrez utiliser une approche différente pour voir le l'image tout autour de la forme comme ceci:

tooltip like element with a triangle over an image

Le but est d'utiliser deux fois la même image. Une fois dans l'élément div et une fois dans le triangle et les positionner exactement au même endroit avec un positionnement absolu. La flèche est faite avec transform:rotate(); .

DÉMO

body{
  padding-top:100px;
  background:url('https://farm8.staticflickr.com/7187/6895047173_d4b1a0d798.jpg')no-repeat center center;
  background-size:cover;
}

.wrap, .img {
  display:inline-block;
  position:relative;
}
.tr{
  position:absolute;
  overflow:hidden;
  top:-25px; left:100px;
  width:50px; height:50px;
  -webkit-transform:rotate(45deg);
  -ms-transform:rotate(45deg);
  transform:rotate(45deg);
}
.tr img{
  position:absolute;
  top:-15px; left:-100px;
  -webkit-transform-Origin: 125px 40px;
  -ms-transform-Origin: 125px 40px;
  transform-Origin: 125px 40px;
  -webkit-transform:rotate(-45deg);
  -ms-transform:rotate(-45deg);
  transform:rotate(-45deg);
}
.img{
  overflow:hidden;
  width: 600px; height:100px;
}
.img img{
  position:absolute;
  top:-40px;
}
<div class="wrap">
    <div class="img">
        <img src="https://farm7.staticflickr.com/6092/6227418584_d5883b0948.jpg" alt="" />
    </div>
     <div class="tr">
        <img src="https://farm7.staticflickr.com/6092/6227418584_d5883b0948.jpg" alt="" />
    </div>
</div>

DÉMO avec des ombres de boîte.

5. SVG et cliPath

DÉMO en utilisant une balise svg et clipPath.
Cela pourrait être une meilleure approche sémantique si vous faites des graphiques.

107
web-tiki

Approche simple

  • Utilisez un pseudo-élément avec box-shadow Et transform: rotate();

  • Ajoutez overflow: hidden; À la div principale.

Extrait:

body {
  margin: 0;
  padding: 0;
  background: url(http://i.imgur.com/EinPKO3.jpg);
  background-size: cover;
}
div {
  height: 100px;
  width: 100%;
  position: absolute;
  bottom: 0;
  overflow: hidden;
}
div:before {
  position: absolute;
  top: -50px;
  left: calc(50% - 35px);
  content: "";
  height: 50px;
  width: 50px;
  background: transparent;
  -webkit-transform-Origin: 0% 100%;
  -moz-transform-Origin: 0% 100%;
  -ms-transform-Origin: 0% 100%;
  transform-Origin: 0% 100%;
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
  box-shadow: 0 0 0 5000px rgba(0, 0, 0, 0.6);
}
<div></div>
5
The Pragmatick

Voici une solution utilisant CSS clip-path qui ne déborde pas le wrapper.

.wrap {
  position:relative;
  width:480px;
  height:270px;
  background-image:url(http://placehold.it/480x270);
}

.wrap:after {
  content:"";
  display:block;
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  height:50px;
  background-color:rgba(0, 0, 0, 0.7);
  -webkit-clip-path:polygon(0 0, calc(50% - 30px) 0, 50% 50%, calc(50% + 30px) 0, 100% 0, 100% 100%, 0 100%);
  -moz-clip-path:polygon(0 0, calc(50% - 30px) 0, 50% 50%, calc(50% + 30px) 0, 100% 0, 100% 100%, 0 100%);
  clip-path:polygon(0 0, calc(50% - 30px) 0, 50% 50%, calc(50% + 30px) 0, 100% 0, 100% 100%, 0 100%);
}
<div class="wrap"></div>
2
ArcadeRenegade