Shape resembling a compass pointer or inner part of a Safari logo

痞子三分冷 提交于 2019-11-30 07:24:46

For a needle resting on its tip

Yes, it is possible to create that shape using only CSS. You have to rotate the shape along both the Y-axis and the Z-axis to achieve it.

Rotating it along the Z-axis by 45 degrees will produce a diamond shape (as indicated in the question) and rotating it along the Y-axis by close to (but less than) 90 degrees will make only a part of the shape visible from the front and thereby would give it the appearance of having shorter diagonal lines (resembling a compass pointer).

Additionally adding a linear-gradient for the background and a inset box-shadow will help to achieve a shape that is a lot closer to the shape shown in question.

body {
  background: #333;
  font-family: Calibri;
  font-size: 18px;
}
div {
  height: 200px;
  width: 150px;
  display: inline-block;
  vertical-align: middle;
  color: white;
  padding-top: 40px;
}
.separator {
  background: #555;
  top: 40px;
  padding-top: 0px;
  height: 160px;
  width: 160px;
  background-image: linear-gradient(-45deg, #555 0%, #555 40%, #444 50%, #333 97%);
  box-shadow: inset 6px 6px 22px 8px #272727;
  transform: rotateY(87deg) rotate(45deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div>
  Some lengthy paragraph content which wraps around when it exceeds the width
</div>
<div class='separator'></div>
<div>
  Some lengthy paragraph content which wraps around when it exceeds the width
</div>


For a needle resting on its base

For a needle that is resting on its base, the rotation should be along the X-axis and Z-axis instead of along Y-axis and Z-axis for the needle resting on its tip. Below is a sample snippet.

body {
  background: #AAA;
  font-family: Calibri;
  font-size: 18px;
}
div {
  height: 200px;
  width: 150px;
  display: inline-block;
  vertical-align: middle;
  color: white;
  padding-top: 40px;
  margin: 40px;
}
.separator {
  background: #555;
  top: 40px;
  padding-top: 0px;
  height: 160px;
  width: 160px;
  background-image: linear-gradient(-45deg, #555 0%, #555 40%, #444 50%, #333 97%);
  box-shadow: inset 6px 6px 22px 8px #272727;
  transform: rotateX(87deg) rotate(45deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='separator'></div>

Compass Pointer created using above method:

Here is a sample compass pointer (inspired in part by the Safari logo) created purely using CSS. The pointer or the needle inside is created using the method explained above.

.container {
  position: relative;
  height: 152px;
  width: 152px;
  padding: 10px;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, white 58%, #999 70%, #EEE 80%);
  border: 1px solid #AAA;
}
.dial {
  height: 150px;
  width: 150px;
  border-radius: 50%;
  background: linear-gradient(#1ad4fd, #1d65f0 100%);
  border: 1px solid #999;
  position: relative;
  animation: rotatedial 2s 6 alternate forwards;
}
.dial:after {
  content: '';
  position: absolute;
  top: 25px;
  left: 25px;
  height: 100px;
  width: 100px;
  background-image: linear-gradient(-45deg, white 0%, white 47%, red 50%);
  box-shadow: inset 0px 6px 22px 0px #CCC, inset -6px -6px 22px 0px #AAA;
  transform: rotateY(85deg) rotate(45deg);
}
.dial:before {
  content: '';
  position: absolute;
  top: 72px;
  left: 70px;
  height: 8px;
  width: 8px;
  background: radial-gradient(circle at 50% 50%, white 30%, grey 100%);
  border: 1px solid #999;
  border-radius: 50%;
  z-index: 2;
}
.hands,
.hands-small {
  position: absolute;
  height: 150px;
  width: 150px;
  top: 11.25px;
  left: 11px;
  z-index: 0;
}
.hands:before,
.hands:after,
.hands .hand:before,
.hands .hand:after {
  content: '';
  position: absolute;
  top: 0;
  left: 74.5px;
  width: 1px;
  height: 12px;
  background: #EEE;
  border-radius: 4px;
  box-shadow: 0px 138px #EEE;
  transform-origin: 50% 75px;
}
.hands-small:before,
.hands-small:after,
.hands-small .hand-small:before,
.hands-small .hand-small:after {
  content: '';
  position: absolute;
  top: 0;
  left: 74.5px;
  width: 1px;
  height: 7px;
  background: #EEE;
  border-radius: 4px;
  box-shadow: 0px 143px #EEE;
  transform-origin: 50% 75px;
}
.hands:before {
  transform: rotate(-45deg);
}
.hands:after {
  transform: rotate(0deg);
}
.hand:before {
  transform: rotate(45deg);
}
.hand:after {
  transform: rotate(90deg);
}
.hands-small:before {
  transform: rotate(-22.5deg);
}
.hands-small:after {
  transform: rotate(22.5deg);
}
.hand-small:before {
  transform: rotate(67.5deg);
}
.hand-small:after {
  transform: rotate(112.5deg);
}
@keyframes rotatedial {
  0% {
    transform: rotate(35deg);
  }
  100% {
    transform: rotate(15deg);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="container">
  <div class="dial"></div>
  <div class="hands">
    <div class="hand"></div>
  </div>
  <div class="hands-small">
    <div class="hand-small"></div>
  </div>
</div>


If you stumbled on this page looking for a SVG implementation, have a look at the below snippet:

.separator {
    position: relative;
    width: 12px;
}
svg {
    position: absolute;
    top: 0px;
    left: 0px;
    height: 100%;
    width: 100%;
}
path {
    fill: url(#MyGradient);
}
path#shade {
    stroke: #2E2E2E;
    stroke-width: 3;
}

/* Just for the demo to style the divs and position */

body {
    background: #333;
    font-family: Calibri;
    font-size: 18px;
}
.container {
    display: flex;
}
.container > .content {
    flex: 1;
    flex-grow: 1;
    color: white;
    margin: 20px;
}
<div class='container'>
    <div class='content'>Some lengthy paragraph content which wraps around when it exceeds the width.Some lengthy paragraph content which wraps around when it exceeds the width.Some lengthy paragraph content which wraps around when it exceeds the width.</div>
    <div class='separator'>
        <svg viewBox='0 0 10 200' preserveAspectRatio='none'>
            <defs>
                <linearGradient id="MyGradient" x1=' 50% ' y1='0% ' x2='50% ' y2='100% '>
                    <stop offset="0%" stop-color="#333" />
                    <stop offset="100%" stop-color="#555" />
                </linearGradient>
            </defs>
            <path d='M0,100 5,0 10,100 z' id='shade' />
            <path d='M0,100 5,0 10,100 5,200 z ' />
        </svg>
    </div>
    <div class='content '>Some lengthy paragraph content which wraps around when it exceeds the width.Some lengthy paragraph content which wraps around when it exceeds the width.Some lengthy paragraph content which wraps around when it exceeds the width.</div>
</div>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!