仅使用伪元素创建 css 徽章

create css badge with pseudo-element only

我有一个可以定位的已知 ID 元素。我怎样才能只使用 css 来创建这样的畅销书徽章?我无法更改 html.

我知道如何创建它,但前提是我可以编辑 html,但我不能:

.box {
  width: 200px; height: 300px;
  position: relative;
  border: 1px solid #BBB;
  background: #EEE;
}
.ribbon {
  position: absolute;
  right: -5px; top: -5px;
  z-index: 1;
  overflow: hidden;
  width: 75px; height: 75px;
  text-align: right;
}
.ribbon span {
  font-size: 10px;
  font-weight: bold;
  color: #FFF;
  text-transform: uppercase;
  text-align: center;
  line-height: 20px;
  transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
  width: 100px;
  display: block;
  background: #79A70A;
  background: linear-gradient(#9BC90D 0%, #79A70A 100%);
  box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1);
  position: absolute;
  top: 19px; right: -21px;
}
.ribbon span::before {
  content: "";
  position: absolute; left: 0px; top: 100%;
  z-index: -1;
  border-left: 3px solid #79A70A;
  border-right: 3px solid transparent;
  border-bottom: 3px solid transparent;
  border-top: 3px solid #79A70A;
}
.ribbon span::after {
  content: "";
  position: absolute; right: 0px; top: 100%;
  z-index: -1;
  border-left: 3px solid transparent;
  border-right: 3px solid #79A70A;
  border-bottom: 3px solid transparent;
  border-top: 3px solid #79A70A;
}
<div class="box">
   <div class="ribbon"><span>Bestseller</span></div>
</div>

问题是我只有母盒,里面没有丝带。我无法输入 html.

因为在伪元素中你不能放置任何 html 标记,你需要聪明地使用简单的形状并将它们组合在一起。此外,您不能有多个 :after 伪元素,因此我们仅限于两种形状(一种用于 :after,一种用于 :before)。 :after 中的那个可能是徽章正面的畅销书,带有文字。最棘手的部分是让 clip-path: polygon(...points) 正确,以便我们获得修剪色带的效果。幸运的是,Firefox 开发工具有一个非常有用的漂亮的多边形修改工具。获得产生“环绕”效果的两个小角有点棘手,但是将它放在一个带有 z-index: -1:before 伪元素中并稍微手动调整偏移量就可以了。最终效果如下:

.box {
  width: 200px; height: 300px;
  position: relative;
  border: 1px solid #BBB;
  background: #EEE;
  margin: 20px;
  display: inline-block;
}
.bestseller:before {
  content: "";
  z-index: -1;
  overflow: hidden;
  transform: rotate(-135deg);
  width: 120px;
  display: block; 
  background: #79A70A;
  background: linear-gradient(#9BC90D 0%, #79A70A 100%);
  box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1);
  position: absolute;
  top: 34px;
  right: -16px;
  clip-path: polygon(120px 20px, 90px -10px, 30px -10px, 0px 20px, 10px 30px,  110px 30px);
  height: 20px;
  width: 120px;
}
.bestseller:after {
  content: "bestseller";
  z-index: 1;
  overflow: hidden;
  font-size: 10px;
  font-weight: bold;
  color: #FFF;
  text-transform: uppercase;
  text-align: center;
  line-height: 20px;
  transform: rotate(45deg);
  width: 120px;
  display: block; 
  background: #79A70A;
  background: linear-gradient(#9BC90D 0%, #79A70A 100%);
  box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1);
  position: absolute;
  top: 20px; right: -30px;
  clip-path: polygon(120px 20px, 90px -10px, 30px -10px, 0px 20px, 10px 30px,  110px 30px)
}
<div class="box">
</div>

<div class="box bestseller">
</div>

仅在CSS的帮助下使用伪class,我们无法创建完全相同但类似的是可能的。使用 class "box" 将 id "ribbon" 添加到 div 并尝试使用下面的 css。 Increment/decrement 高度、右上角等基于您 div 的大小。

#ribbon:before {
    content: "";
    width: 60px;
    display: block;
    position: absolute;
    top: 14px;
    right: -28px;
    transform: rotate(45deg);
    -webkit-transform: rotate(45deg);
    border-left: 30px solid transparent;
    border-right: 30px solid transparent;
    border-bottom: 30px solid green;
    height: 0;
}

#ribbon:after {
    content: "Bestseller";
    font-size: 10px;
    font-weight: bold;
    color: #FFF;
    text-transform: uppercase;
    text-align: center;
    line-height: 30px;
    transform: rotate(45deg);
    -webkit-transform: rotate(45deg);
    width: 60px;
    display: block;
    position: absolute;
    top: 14px;
    right: 2px;
    height: 30px;
}

除了尝试使用边框作为功能区的背景颜色,您还可以尝试使用功能区图像作为背景并使用其上方的文本。