2

I have been going through how different shapes can be drawn by css. I have encountered the following css code which draws a small arrow shape:

#curvedarrow {
  position: relative;
  width: 0;
  height: 0;
  border-top: 9px solid transparent;
  border-right: 9px solid red;
  -webkit-transform: rotate(10deg);
  -moz-transform: rotate(10deg);
  -ms-transform: rotate(10deg);
  -o-transform: rotate(10deg);
}
#curvedarrow:after {
  content: "";
  position: absolute;
  border: 0 solid transparent;
  border-top: 3px solid red;
  border-radius: 20px 0 0 0;
  top: -12px;
  left: -9px;
  width: 12px;
  height: 12px;
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -o-transform: rotate(45deg);
}

I completely understand how the tip of the arrow is drawn as I hide the tail (arrow:after) and this post really helped me a lot to understand most of the shapes drawn.

Yet I am stuck how the border is used to draw the tail.enter image description here (I hid the tip by setting it transparent). Here is my jsfiddle also.

I see that he set only left-top corner border radius by border-radius: 20px 0 0 0;, but why the end of the left side of that tail finishes getting smaller but the right side is just like a cut?

I thought that, okay only left-top side corner is drawn(when border-radius takes 4 values, first one is the left-top then top-right etc etc.. ref), so if I add right-top side, it should double the length of the shape yet getting the volume decreased. My second statement is correct, but the length does not change at all. jsfiddle

Red fx
  • 1,071
  • 2
  • 12
  • 26

2 Answers2

3

So basically this is made with a couple of things. I broke down the steps in the following code snippet:

body {
font-family: sans-serif;
}

#circle {
  height: 10px;
  width: 10px;
  border: 5px solid red;
  border-radius: 50%;
}

#circle2 {
  height: 10px;
  width: 10px;
  border: 5px solid red;
  border-radius: 50% 0 0 0;
}

#circle3 {
  height: 10px;
  width: 10px;
  border: solid;
  border-color: red transparent transparent transparent;
  border-width: 5px;
  border-radius: 50% 0 0 0;
}

#circle4 {
  height: 10px;
  width: 10px;
  border: solid;
  border-color: red transparent transparent transparent;
  border-width: 5px;
  border-radius: 50% 0 0 0;
  transform: rotate(45deg);
}

#circle5 {
  height: 10px;
  width: 12px;
  border: solid;
  border-color: red transparent transparent transparent;
  border-width: 5px 0 0 0;
  border-radius: 50% 0 0 0;
  transform: rotate(45deg);
}

#circle6 {
  width: 12px;
  height: 12px;
  border: solid;
  border-color: red transparent transparent transparent;
  border-width: 3px 0 0 0;
  border-radius: 20px 0 0 0;
  transform: rotate(45deg);
}

#square {
  height: 10px;
  width: 10px;
  border: 5px solid;
  border-color: red green grey black;
  border-radius: 50%;
}

#square2 {
  height: 10px;
  width: 10px;
  border: 5px solid;
  border-color: red green grey black;
  border-radius: 50% 0;
}

#square3 {
  height: 10px;
  width: 10px;
  border: 5px solid;
  border-color: red green grey black;
  border-radius: 50% 0;
  border-width: 5px 0;
}

.wrapper {
  background: #eeeeee;
  padding: 15px;
}
<p>
  1. Create a circle using border-radius
</p>
<div id="circle">
</div>
<br>
<p>
  2. Change the border-radius so that only one corner has it.
</p>
<div id="circle2">
</div>
<br>
<p>
  3. Remove all the other borders
</p>
<div id="circle3">
</div>
<br>
<p>
  4. Rotate the whole thing
</p>
<div id="circle4">
</div>
<br>
<p>
  5. Set the border-width to zero for all borders except border-top <br>(This creates the "cut" effect you described earlier, as the border-width goes from 5 to zero (from top to left)
</p>
<div class="wrapper">
  <p>
    For further demonstration: The combination of a varying border-radius and border-width creates this effect.</p>
  <p>
    Basic borders:
  </p>
  <div id="square"></div>
  <br>
  <p>
    Varying border-radius:
  </p>
  <div id="square2"></div>
  <br>
  <p>
    Varying border-radius and border-width:
  </p>
  <div id="square3"></div>
  <br>
  <p>
   Result:
  </p>
<div id="circle5">
</div>
</div>
<br>
<p>
  6. Change up the values
</p>
<div id="circle6">
</div>
<br>
<p>
  7. And you're done!
</p>
<div id="curvedarrow"></div>
Maharkus
  • 2,841
  • 21
  • 35
0

you pretty much can read CSS like a step by step procedure

#curvedarrow:after {
  content: "";
  position: absolute;
  border: 0 solid transparent; // make sure NO border is displayed
                               //   it also makes the size of the 
                               //   borders = 0 in order to be 
                               //   able to do that "pointy" effect at
                               //   the end of the tail

  border-top: 3px solid red;   // make a border on the top of the box and
                               // make it 3 pixels thick. this will be the
                               // final size of the transition

  border-radius: 20px 0 0 0;   // round the top left corner of the box
                               // (the one you actually see) with a 
                               // radius of 20 pixels. Since in goes from 
                               // 0 pxiels to 3 during this transformation,
                               // it will smoothly do so. Resulting in 
                               // a "pointy" effect for the tail. if you
                               // want a staring tail, just use the same 
                               // border size for the whole border

  //those are basicaly just placing the tail at the right place
  top: -12px;
  left: -9px;
  width: 12px;
  height: 12px;

  // rotate the tail 45 deg to the right.
  // since each browser my act differently to `transform: rotate(45deg)`
  // the code here just makes sure each browser uses it's own rotation
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -o-transform: rotate(45deg);
}
Sirmyself
  • 1,464
  • 1
  • 14
  • 29