Search code examples
htmlcsscss-shapes

CSS - Arrow not lining up


I am trying tro create a pure CSS arrow with a line like this...

.arrow {
	position:absolute;
	left:50%;
}

.arrow_line {
	width:2px;
	background:darkblue;
  height:60px;
	margin:auto;
}

.arrow_point {
	box-sizing: border-box;
	height: 25px;
	width: 25px;
	border-style: solid;
	border-color: darkblue;
	border-width: 0px 2px 2px 0px;
	transform: rotate(45deg);
	transition: border-width 150ms ease-in-out;
	margin-top: -24px;
}
<div class="arrow">
  <div class="arrow_line"></div>
  <div class="arrow_point"></div>
</div>

The vertical line never quite seems to line up vertically with the arrow, I have left it slightly adrift in the example to better demonstrate that it is not centered in relation to the arrow.

Is there a better way to create a CSS arrow?


Solution

  • You can use one element and gradient then you won't have issue with centring:

    .arrow {
      width:80px;
      height:80px;
      background:
        linear-gradient(blue,blue) bottom right/40px 4px,
        linear-gradient(blue,blue) bottom right/4px 40px,
        linear-gradient(
        to top right,
        transparent calc(50% - 2px),
        blue        calc(50% - 2px),
        blue        calc(50% + 2px),
        transparent calc(50% + 2px));
      background-repeat:no-repeat;
      transform:rotate(45deg);
      margin:20px;
    }
    <div class="arrow">
    </div>

    You can also easily adjust the size:

    .arrow {
      width:var(--s,80px);
      height:var(--s,80px);
      background:
        linear-gradient(blue,blue) bottom right/calc(var(--s,80px)/2) calc(var(--t,2px)*2),
        linear-gradient(blue,blue) bottom right/calc(var(--t,2px)*2) calc(var(--s,80px)/2),
        linear-gradient(
        to top right,
        transparent calc(50% - var(--t,2px)),
        blue        calc(50% - var(--t,2px)),
        blue        calc(50% + var(--t,2px)),
        transparent calc(50% + var(--t,2px)));
      background-repeat:no-repeat;
      transform:rotate(45deg);
      margin:20px;
      display:inline-block;
    }
    <div class="arrow">
    </div>
    
    <div class="arrow" style="--t:3px;--s:60px">
    </div>
    
    <div class="arrow" style="--t:1px;--s:40px">
    </div>
    
    <div class="arrow" style="--t:2px;--s:20px">
    </div>
    
    <div class="arrow" style="--t:1px;--s:20px">
    </div>