0

I use the code like these to create a css triangle, but to center it inside its container turns out to be difficult.

.arrow-down {
  display: inline-block;
  border-top: 4px solid #838990;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
}

The container div is a square with width/height set. BUT it does not use flexbox. If I can use flexbox then align-items: center; justify-content: center; can do the trick but without flexbox it is hard.

For example margin: auto; or left:50% won't do it. But strangely setting position: absolute; left:50%; top:50%; can center it vertically. Not sure why it can only do it vertically.

----- update -----

From the answer I got, add transform: translate(-50%,-50%); do the trick, but why ?

Qiulang
  • 10,295
  • 11
  • 80
  • 129

5 Answers5

3

Give the below css property:

.arrow-down{
display: inline-block;
border-top: 4px solid #838990;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
transform: -webkit-translate(-50%,-50%);
transform: -o-translate(-50%,-50%);
transform: -moz-translate(-50%,-50%);
transform: -mz-translate(-50%,-50%);

}

and add "position:relative" to the outside div.

Fahim Khan
  • 395
  • 2
  • 7
1

Why transform translate works:

Adding to Fahim Khan's answer, Using transform: translate(-50%,-50%); does the trick because when you use left: 50% and top: 50%, you are in a sense starting horizontally at 50% from the left and 50% from the top but not accounting for the width and height of the triangle itself.

You can think of it this way to understand it: Let's assume that the width of the container is 100px and width of triangle is 40px. The browser begins drawing the triangle from the 50th pixel and then it extends up to the 90th pixel. The same happens vertically.

Here, we are not accounting for the width and height of the triangle itself. To correct this, we need to start at the 30th pixel, this would mean that the the triangle would end at the 70th pixel, placing it right at the center. For this we use transformX(-50%) => meaning "move my body 50% up" and translateX(-50%) => meaning "move my body 50% to the left".

In conclusion, these are what are necessary to position it at the center for the child element:

position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);

And for the parent element, don't forget to add: position: relative;

Winston Jude
  • 569
  • 2
  • 11
0

Please try this code

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <style>
  .box{
   height: 200px;
   width:200px;
   background-color: #dddddd;
   text-align: center;
   position: relative;
  }
  .arrow-down {
   display: inline-block;
   border-top: 4px solid #838990;
   border-left: 4px solid transparent;
   border-right: 4px solid transparent;
   transform: translateY(-50%) translateX(-50%);
   top: 50%;
   position: absolute;
   left: 50%;
  }
 </style>
</head>
<body>
 <div class="box">
  <div class="arrow-down"></div>
 </div>
</body>
</html>
Vikas Patel
  • 207
  • 1
  • 10
0
  .parent{
    text-align: center;
    width:100%;
    height:100vh;
    position:relative;
    display: table;
  }
  .row{
    display: table-cell; 
    vertical-align:middle;
    text-align: center; 
    width:100%;
  }
  .arrow-down {  
    border-top: 4px solid #838990;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent; 
    display:inline-block;

  }
<div class="parent">
  <div class="row">
   <div class="arrow-down"></div>
  </div>
</div>
0

This is how you add the arrows using pseudo classes.. I have made them centered in using table.

.bg-green {
  display: table;
  background: #0f0;
  height: 50px;
  width: 100%;
  text-align: center;
}
.arrow {
  position: relative;
  display: table-cell;
  height: 10px;
  width: 10px;
}
.arrow::before {
  content: '';
  position: absolute;
  right: 50%;
  top: 50%;
  border: 4px solid #000;
}
.arrow.up::before {
  border-top-color: transparent;
  border-left-color: transparent;
  border-right-color: transparent;
}
.arrow.down::before {
  border-bottom-color: transparent;
  border-left-color: transparent;
  border-right-color: transparent;
}
.arrow.right::before {
  border-top-color: transparent;
  border-bottom-color: transparent;
  border-right-color: transparent;
}
.arrow.left::before {
  border-top-color: transparent;
  border-left-color: transparent;
  border-bottom-color: transparent;
}
<div class="bg-green">
  <span class="arrow up"></span>
  <span class="arrow down"></span>
  <span class="arrow left"></span>
  <span class="arrow right"></span>
</div>
Adarsh Mohan
  • 1,364
  • 1
  • 9
  • 14