Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make an arrow shape with responsive width and only CSS

I'm trying to make a container that has an upward arrow attached to it. I am familiar with the border drawing trick and think that's a likely solution, but it only works for known sizes I think, since you have to specify border in em or px.

The shape I would like to make is this:

          .
         / \
        /   \
       /     \
      | flex  |
      |       |

Where the content area can flex to different sizes as a percentage of a parent container.

Here is the CSS, with the problem area flagged:

.metric {
    display: inline-block;
    position: relative;
    height: 150px;
    width: 50%;
    background: lawngreen;
}

.metric:after {
    position: absolute;
    top: -25px;
    left: 0;
    content: '';
    background: white;
    width: 100%;
    height: 0;
    border: 75px solid white; /* this fixed width is the problem */
    border-top: none;
    border-bottom: 25px solid lawngreen;
    box-sizing: border-box;
}

Here is the jsfiddle: http://jsfiddle.net/C8XJW/2/

Do you guys know any way to pull this off?

like image 228
SimplGy Avatar asked Feb 17 '23 01:02

SimplGy


2 Answers

Here is another posibility.

This one does the trick with gradient backgrounds. You need 2 of them, so that the diagonal is easily achieved:

Relevant CSS:

.metric:before, .metric:after {
    position: absolute;
    top: -25px;
    content: '';
    width: 50%;
    height: 25px;
}
.metric:before {
    left: 0px;
    background: linear-gradient(to right bottom, transparent 50%, lawngreen 50%);
}
.metric:after {
    right: 0px;
    background: linear-gradient(to left bottom, transparent 50%, lawngreen 50%);
}

Updated Fiddle

The differences with Simple As Could Be solution:

Pro Transparent corners (relevant if you have a background)

Con Worse browser support

like image 154
vals Avatar answered Feb 18 '23 13:02

vals


Here's one great solution. Bascially, you make the arrow always centered, and bigger than you'd ever need it, but lop off the overflow.

Here's the JSFiddle: http://jsfiddle.net/nBAK9/4/

And here's the interesting code:

.metric:after {
  position: absolute;
  top: 0;
  left: 50%;
  margin-left: -250px;            /* max expected width /2 */
  content: '';
  background: white;
  width: 500px;                   /* max expected width    */
  height: 0;
  border: 250px solid white;      /* max expected width /2 */
  border-top: none;
  border-bottom: 50px solid #cf6; /* This size adjusts the slope of the triangle */
  box-sizing: border-box;
}
like image 28
SimplGy Avatar answered Feb 18 '23 13:02

SimplGy