Как часто вам попадаются в дизайнах различные иконки в виде стрелочек, сердечек, тултипчиков и прочего? Как правило, мы их выкачиваем, добавляем как картинку либо встраиваем в спрайт. Однако подавляющее большинство популярных иконок и стрелок можно сделать средствами CSS. Да, возможно с некоторыми придется немного заморочиться. Но вы только подумайте о результате - это и сэкономленные байты (а то и килобайты), и уменьшение запросов к серверу.

Суть реализации любой иконки или даже полноценного рисунка проста - она будет состоять из мелких застиленных блоков и применения псевдоэлементов :before и :after. Далее, комбинируя свойства позиционирования и трансформации, вырисовываются детали, из которых будет состоять фигура.

Конечно, мы также можем применить свойства clip-path для создания нужной нам формы, но об этом в отдельной статье. В этой сосредоточимся на, казалось бы, примитивном, но в то же время очень важном подходе - "чем проще - тем лучше". Ниже предоставлены наиболее популярные фигуры и (по клику) способ их реализации средствами CSS.

Геометрические фигуры с помощью CSS

HTML
<div class="square"></div>
CSS
.square {
  font-size: 10px;
  width: 18em;
  height: 18em;
  background: black;
}
HTML
<div class="rectangle"></div>
CSS
.rectangle {
  font-size: 10px;
  width: 20em;
  height: 13em;
  background: black;
}
HTML
<div class="rhombus"></div>
CSS
.rhombus {
  font-size: 10px;
  position: relative;
  border-style: none solid solid solid;
}
.rhombus,
.rhombus:before {
  width: 0;
  height: 0;
  border-color: black transparent;
  border-width: 10.5em 7em;
}
.rhombus:before {
  content: "";
  position: absolute;
  left: -7em;
  border-style: solid solid none solid;
  top: 10.5em;
}
HTML
<div class="circle"></div>
CSS
.circle {
  font-size: 10px;
  width: 18em;
  height: 18em;
  background: black;
  border-radius: 50%;
}
HTML
<div class="oval"></div>
CSS
.oval {
  font-size: 10px;
  width: 15em;
  height: 21em;
  background: black;
  border-radius: 28.5em 28.5em
                 28.5em 28.5em/
                 47.6em 47.6em
                 33.3em 33.3em;
}
HTML
<div class="ellipse"></div>
CSS
.ellipse {
  font-size: 10px;
  width: 21em;
  height: 13.4em;
  background: black;
  border-radius: 50%;
}
HTML
<div class="quadrifoil"></div>
CSS
.quadrifoil {
  font-size: 10px;
  width: 21em;
  border-color: black transparent;
  border-style: none solid solid solid;
  border-width: 11.4em 2.8em;
}
HTML
<div class="parallelogram"></div>
CSS
.parallelogram {
  font-size: 10px;
  width: 18em;
  height: 12em;
  background-color: black;
  transform: translate(-50%, -50%)
             skewX(20deg);
}
HTML
<div class="quad"></div>
CSS
.quad {
  font-size: 10px;
  width: 21em;
  border-color: black transparent;
  border-style: none solid solid solid;
  border-width: 0 6em 11em 0;
}
HTML
<div class="equilateral-triangle"></div>
CSS
.equilateral-triangle {
  font-size: 10px;
  width: 0;
  height: 0;
  border-color: black transparent;
  border-width: 17em 8em;
  border-style: none solid solid solid;
}
 
HTML
<div class="rectangular-triangle"></div>
CSS
.rectangular-triangle {
  font-size: 10px;
  width: 0;
  height: 0;
  border-right: 17em solid transparent;
  border-bottom: 17em solid black;
}
HTML
<div class="curvilinear-triangle">
  <span class="segment segment-1"></span>
  <span class="segment segment-2"></span>
  <span class="segment segment-3"></span>
</div>
CSS
.curvilinear-triangle {
  font-size: 10px;
  width: 0;
  height: 0;
  border-color: black transparent;
  border-width: 16.5em 9.5em;
  border-style: none solid solid solid;
  position: relative;
}
.curvilinear-triangle .segment {
  position: absolute;
  width: 19em;
  height: 1.9em;
  top: 7.3em;
  left: -9.5em;
  overflow: hidden;
}
.curvilinear-triangle .segment:before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  width: 49.48em;
  height: 49.48em;
  background-color: black;
  border-radius: 50%;
}
.curvilinear-triangle .segment-1 {
  transform: rotate(-60deg)
             translate(-2.38em, -5.04em);
}
.curvilinear-triangle .segment-2 {
  transform: rotate(60deg)
             translate(2.38em, -5.04em);
}
.curvilinear-triangle .segment-3 {
  transform: rotate(180deg)
             translate(0, -9.13em);
}
HTML
<div class="pentagon"></div>
CSS
.pentagon {
  font-size: 10px;
  width: 18.46em;
  border-color: black transparent;
  border-style: solid solid none solid;
  border-width: 10.83em 3.5em;
  margin-top: 3.32em;
  position: relative;
}
.pentagon:before {
  content: "";
  position: absolute;
  width: 0;
  height: 0;
  bottom: 10.8em;
  left: 50%;
  transform: translateX(-50%);
  border-style: none solid solid solid;
  border-color: black transparent;
  border-width: 6.7em 9.2em;
}
HTML
<div class="hexagon"></div>
CSS
.hexagon {
  font-size: 10px;
  width: 9.7em;
  height: 16.8em;
  background-color: black;
  position: relative;
}
.hexagon:before,
.hexagon:after {
  content: "";
  position: absolute;
  top: 0;
  width: 0;
  height: 0;
  border-color: transparent black;
  border-width: 8.38em 4.83em;
}
.hexagon:before {
  border-style: solid solid solid none;
  right: 100%;
}
.hexagon:after {
  border-style: solid none solid solid;
  left: 100%;
}
HTML
<div class="octogon"></div>
CSS
.octogon {
  font-size: 10px;
  width: 17em;
  height: 7em;
  background: black;
  position: relative;
}
.octogon:before,
.octogon:after {
  content: "";
  position: absolute;
  left: 0;
  width: 7em;
  border-color: black transparent;
  border-width: 4.96em;
}
.octogon:before {
  bottom: 100%;
  border-style: none solid solid solid;
}
.octogon:after {
  top: 100%;
  border-style: solid solid none solid;
}

Другие популярные фигуры с помощью CSS

HTML
<div class="five-point-star"></div>
CSS
.five-point-star {
  font-size: 10px;
  position: relative;
}
.five-point-star,
.five-point-star:before,
.five-point-star:after {
  width: 0;
  height: 0;
  border-color: black transparent;
  border-width: 6.17em 9.5em;
  border-style: solid solid none solid;
}
.five-point-star:before,
.five-point-star:after {
  content: "";
  position: absolute;
}
.five-point-star:before {
  transform: rotate(72deg);
  margin-top: -12.85em;
  transform-origin: left top;
}
.five-point-star:after {
  transform: rotate(-72deg);
  margin-top: 1.05em;
  transform-origin: left bottom;
}
HTML
<div class="six-point-star">
  <div class="inner inner1"><i></i></div>
  <div class="inner inner2"><i></i></div>
  <div class="inner inner3"><i></i></div>
</div>
CSS
.six-point-star {
  font-size: 10px;
  width: 13.3em;
  height: 13.3em;
  position: relative;
}
.six-point-star .inner,
.six-point-star .inner i,
.six-point-star .inner i:before {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
}
.six-point-star .inner i {
  transform: scaleX(0.3);
}
.six-point-star .inner i:before {
  content: "";
  background-color: black;
  transform: rotate(45deg);
}
.six-point-star .inner2 {
  transform: rotate(60deg);
}
.six-point-star .inner3 {
  transform: rotate(120deg);
}
HTML
<div class="david-star"></div>
CSS
.david-star {
  font-size: 10px;
  width: 0;
  height: 0;
  border-color: black transparent;
  border-width: 14.83em 8.54em;
  border-style: none solid solid solid;
  position: relative;
}
.david-star:before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  transform: rotate(180deg) translateX(50%);
  border-color: black transparent;
  border-width: 14.83em 8.54em;
  border-style: none solid solid solid;
  margin-top: 4.76em;
}
HTML
<div class="heart"></div>
CSS
.heart {
  font-size: 10px;
  width: 17.13em;
  height: 17.13em;
  position: relative;
}
.heart:before,
.heart:after {
  content: "";
  position: absolute;
  bottom: 0;
  background-color: black;
  width: 100%;
  height: 60%;
}
.heart:before {
  transform-origin: right bottom;
  right: 50%;
  border-radius: 9.5em 0 0 9.5em;
  transform: rotate(45deg);
}
.heart:after {
  left: 50%;
  border-radius: 0 9.5em 9.5em 0;
  transform-origin: left bottom;
  transform: rotate(-45deg);
}
HTML
<div class="eye">
  <div class="inner inner1"></div>
  <div class="inner inner2"></div>
</div>
CSS
.eye {
  font-size: 10px;
  width: 5.7em;
  height: 5.7em;
  border-radius: 50%;
  background: black;
  position: relative;
}
.eye .inner {
  width: 21.9em;
  height: 7.6em;
  overflow: hidden;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}
.eye .inner1 {
  bottom: 50%;
}
.eye .inner2 {
  top: 50%;
}
.eye .inner:before {
  content: "";
  position: absolute;
  left: 50%;
  transform: translateX(-50%) scaleY(0.9);
  width: 19em;
  height: 19em;
  border: 1.8em solid black;
  border-radius: 50%;
}
.eye .inner1:before {
  top: 0;
}
.eye .inner2:before {
  bottom: 0;
}
HTML
<div class="like">
  <div class="hand">
    <div class="thumb"></div>
    <div class="fingers-2-3"></div>
    <div class="fingers-4-5"></div>
  </div>
</div>
CSS
.like {
  font-size: 10px;
  width: 17.1em;
  height: 17.1em;
  position: relative;
}
.like .hand {
  position: absolute;
  background-color: black;
  width: 11.42em;
  height: 11.42em;
  bottom: 0;
  left: 0;
  border-radius: 0.95em;
}
.like .hand:before {
  content: "";
  position: absolute;
  top: 0;
  right: calc(100% + 0.48em);
  height: 100%;
  width: 3.9em;
  background-color: black;
  border-radius: 0.95em;
}
.like .thumb {
  position: absolute;
  left: 0;
  height: 85%;
  bottom: 95%;
  width: 3.8em;
  background-color: black;
  border-radius: 1.9em 1.9em 0 0;
  transform-origin: left bottom;
  transform: rotate(30deg);
}
.like .fingers-2-3:before,
.like .fingers-2-3:after,
.like .fingers-4-5:before,
.like .fingers-4-5:after {
  content: "";
  position: absolute;
  background-color: black;
  left: 10%;
  height: 30%;
  border-radius: 4.76em;
}
.like .fingers-2-3:before {
  bottom: 75%;
  width: 115%;
}
.like .fingers-2-3:after {
  bottom: 50%;
  width: 110%;
}
.like .fingers-4-5:before {
  bottom: 25%;
  width: 105%;
}
.like .fingers-4-5:after {
  bottom: 0;
  width: 100%;
}
HTML
<div class="tooltip-right"></div>
CSS
.tooltip-right {
  font-size: 10px;
  width: 18em;
  height: 12.37em;
  border-radius: 0.95em;
  background: black;
  position: relative;
}
.tooltip-right:before {
  content: "";
  width: 0;
  height: 0;
  border-style: solid solid solid none;
  border-color: transparent black;
  border-width: 1.3em 1.88em;
  position: absolute;
  right: 100%;
  top: calc(50% - 0.67em);
}
HTML
<div class="tooltip-angle"></div>
CSS
.tooltip-angle {
  font-size: 10px;
  width: 19em;
  height: 11.42em;
  border-radius: 9.5em/5.7em;
  background: black;
  position: relative;
}
.tooltip-angle:before {
  content: "";
  width: 0;
  height: 0;
  border-style: solid solid solid none;
  border-color: transparent black;
  border-width: 1.3em 7.58em;
  position: absolute;
  right: 100%;
  top: calc(50% - 0.67em);
  transform-origin: right center;
  transform: rotate(-45deg)
             translate(1.9em, 5.71em);
}
HTML
<div class="tooltip-top">
  <div class="inner"></div>
</div>
CSS
.tooltip-top {
  font-size: 10px;
  width: 18.1em;
  height: 11.4em;
  border-radius: 1.9em;
  background: black;
  position: relative;
}
.tooltip-top:before {
  content: "";
  width: 0;
  height: 0;
  border-style: solid solid none solid;
  border-color: black transparent;
  border-width: 3.8em 1.9em;
  position: absolute;
  top: 100%;
  left: calc(50% - 1.9em);
}
.tooltip-top .inner {
  width: 9.5em;
  height: 2.1em;
  position: absolute;
  left: 50%;
  top: 100%;
  transform: translateX(-50%);
  overflow: hidden;
}
.tooltip-top .inner:before,
.tooltip-top .inner:after {
  content: "";
  position: absolute;
  width: 8.56em;
  height: 8.56em;
  border-radius: 50%;
  top: 0;
  box-shadow: 0 0 0 0.9em black;
}
.tooltip-top .inner:before {
  left: -4.1em;
}
.tooltip-top .inner:after {
  right: -4.1em;
}
HTML
<div class="chevron">
  <div class="arrow"></div>
</div>
CSS
.chevron {
  font-size: 10px;
  width: 17.13em;
  height: 17.13em;
  position: relative;
}
.chevron .arrow {
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: hidden;
  transform: scaleX(0.8);
}
.chevron .arrow:before {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  width: 19em;
  height: 19em;
  border: 4.75em solid black;
  transform-origin: right top;
  transform: rotate(45deg);
}
HTML
<div class="nav-arrow">
  <div class="arrow">
    <div class="inner"></div>
  </div>
</div>
CSS
.nav-arrow {
  font-size: 10px;
  width: 11.4em;
  height: 22.8em;
  position: relative;
}
.nav-arrow .arrow {
  position: absolute;
  right: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  transform: scaleY(0.8);
}
.nav-arrow .inner {
  position: absolute;
  top: 50%;
  right: 0;
  width: 19em;
  height: 19em;
  transform-origin: right top;
  transform: rotate(45deg);
  overflow: hidden;
}
.nav-arrow .inner:before {
  content: "";
  position: absolute;
  top: 3.52em;
  right: 3.52em;
  width: 14.27em;
  height: 14.27em;
  box-shadow: 0 0 0 9.52em black;
  transform-origin: right top;
  transform: skew(30deg) rotate(17.3deg);
}
HTML
<div class="lead-arrow"></div>
CSS
.lead-arrow {
  font-size: 10px;
  width: 7.61em;
  height: 7.61em;
  background: black;
  position: relative;
}
.lead-arrow:before {
  content: "";
  width: 0;
  height: 0;
  border-style: solid none solid solid;
  border-color: transparent black;
  border-width: 9.5em;
  position: absolute;
  left: 100%;
  top: 50%;
  transform: translateY(-50%);
}
HTML
<div class="zoom">
  <div class="inner"></div>
</div>
CSS
.zoom {
  font-size: 10px;
  width: 14.27em;
  height: 19em;
  position: relative;
}
.zoom .inner {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 7.61em;
  height: 2.85em;
  background-color: black;
  transform-origin: left center;
  transform: rotate(-45deg);
}
.zoom .inner:before {
  content: "";
  width: 9.5em;
  height: 9.5em;
  border: 1.87em solid black;
  border-radius: 50%;
  position: absolute;
  left: 100%;
  top: 50%;
  transform: translate(-0.9em, -50%);
}
HTML
<div class="flag"></div>
CSS
.flag {
  font-size: 10px;
  width: 11.4em;
  height: 13.3em;
  border-radius: 0.9em 0.9em 0 0;
  background: black;
  position: relative;
}
.flag:after {
  content: "";
  position: absolute;
  width: 0;
  height: 0;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border-style: none solid solid solid;
  border-width: 2.83em 5.7em;
  border-color: transparent black;
}
HTML
<div class="plus"></div>
CSS
.plus {
  font-size: 10px;
  width: 3.8em;
  height: 16.18em;
  border-radius: 0.9em;
  background: black;
  position: relative;
}
.plus:before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%,-50%) rotate(90deg);
  width: 100%;
  height: 100%;
  background-color: black;
  border-radius: 0.9em;
}
HTML
<div class="diamond"></div>
CSS
.diamond {
  font-size: 10px;
  width: 15.22em;
  height: 0;
  border-style: none solid solid solid;
  border-width: 4.76em 3.8em;
  border-color: black transparent;
  position: relative;
}
.diamond:before {
  content: "";
  position: absolute;
  width: 0;
  height: 0;
  left: 50%;
  top: 4.76em;
  transform: translateX(-50%);
  border-style: solid solid none solid;
  border-color: black transparent;
  border-width: 11.42em 7.6em;
}
HTML
<div class="yin-yang">
  <div class="inner inner1"></div>
  <div class="inner inner2"></div>
</div>
CSS
.yin-yang {
  font-size: 10px;
  width: 15.2em;
  height: 15.2em;
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 0 0 0.45em black;
  position: relative;
}
.yin-yang:before {
  content: "";
  position: absolute;
  width: 1.9em;
  height: 1.9em;
  border-radius: 50%;
  background-color: currentColor;
  right: 25%;
  top: 50%;
  transform: translate(50%, -50%);
}
.yin-yang .inner {
  position: absolute;
  width: 50%;
  overflow: hidden;
}
.yin-yang .inner1 {
  top: 25%;
  left: 0;
  bottom: 0;
  border-radius: 3.8em 3.8em 0 0;
}
.yin-yang .inner1:before {
  top: 3.8em;
  width: 1.9em;
  height: 1.9em;
}
.yin-yang .inner2 {
  top: 50%;
  right: 0;
  bottom: 0;
}
.yin-yang .inner2:before {
  top: 0;
  width: 7.6em;
  height: 7.6em;
}
.yin-yang .inner1:before,
.yin-yang .inner2:before {
  content: "";
  position: absolute;
  left: 3.8em;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  box-shadow: 0 0 0 7.6em black;
}
HTML
<div class="moon"></div>
CSS
.moon {
  font-size: 10px;
  width: 15.2em;
  height: 15.2em;
  overflow: hidden;
  position: relative;
}
.moon:before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  box-shadow: -2.85em -2.85em 0 black;
  transform-origin: left center;
  transform: rotate(-45deg)
             translate(1.9em, 9.5em);
}