Pages

Sunday, 24 March 2019

An arrow between Bootstrap cards

Recently I wanted to add an arrow (as in the triangle at the side of a tooltip or popover) pointing one card to its neighbour. It is only a few lines of code, but oddly the solutions available online are overly complex and wasteful. So this is my barebone solution.


To make a triangle, you don't need SVG or anything fancy. Just a rather strange usage of the border-width CSS property. There are a lot of new and cleaver CSS tricks and I am always surprised when I learn a new one like this. Like many properties border-width can control the four sides (top, bottom, left and right) separately and by setting one side to zero (not 0px) it results in that side's being collapsed into a triangle. Do note that the width and height need to be also zero.
This makes a triangle in the default gray in Bootstrap card borders, namely rgba(0, 0, 0, 0.125).

<div style="left:-30px;
            top: 80px;
            position: absolute;
            width: 0;
            z-index:1000;
            height: 0;
            border-style: solid;
            border-width: 30px 30px 30px 0;
            border-color: transparent rgba(0, 0, 0, 0.125) transparent transparent;">
</div>
Another triangle coloured (not filled) with the background, shifted by one will give a 1px border.
<div style="left:-29px;
            top: 80px;
            position: absolute;
            width: 0;
            z-index:1001;
            height: 0;
            border-style: solid;
            border-width: 30px 30px 30px 0;
            border-color: transparent white transparent transparent;">
</div>
Once we are happy with them, you can move them to your stylesheet as pseudoelements, making all very tidy and repeatable.

.arrow-left {
    left:-30px; top: 80px; position: absolute; width: 0; z-index:1000;
    height: 0;
    border-style: solid;
    border-width: 30px 30px 30px 0;
    border-color: transparent rgba(0, 0, 0, 0.125) transparent transparent;

}

.arrow-left:after {
    display: block;
    content: "";
    position: absolute;
    left: 1px; top: -30px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 30px 30px 30px 0;
    z-index:1000;
    border-color: transparent white transparent transparent;
}

.arrow-right {
    right:-30px; top: 80px; position: absolute; width: 0; z-index:1000;
    height: 0;
    border-style: solid;
    border-width: 30px 0px 30px 30px;
    border-color: transparent transparent transparent rgba(0, 0, 0, 0.125);

}

.arrow-right:after {
    display: block;
    content: "";
    position: absolute;
    right: 1px; top: -30px;
    width: 0;
    z-index:1000;
    height: 0;
    border-style: solid;
    border-width: 30px 0px 30px 30px;
    border-color: transparent transparent transparent white;
}
And if the parts move to vertically stacked on a small screen then just copy the code again as top-arrow and use the .d-sm-none and .d-md-block BS4 classes to control them. Easy. No mystery. No overkill JS code.
If you think this is cool, you should check out border-radius and transforms, which allow some very fun things indeed.

No comments:

Post a Comment