Search code examples
htmlcsscss-shapes

Granularity of shapes in CSS


I'm trying to achieve this in html:

enter image description here

I do it like this (in red to make it more obvious):

span.triangle-bottomleft { 
    width: 0;
    height: 0;
    border-bottom: 50px solid red;
    border-right: 500px solid transparent;
}
span.triangle-bottomright {
    width: 0;
    height: 0;
    border-bottom: 50px solid red;
    border-left: 500px solid transparent;
}

The result is this: enter image description here

The pixel is not very granular. Is it possible to make the sloped line smoother?

Thanks!


Solution

  • Based on my little experiment, it seems that anti-aliasing works better with the border width hack than the background image solution. There is no easy CSS-only solution to what you're looking for, unfortunately.

    Give the following markup:

    <div class="chevron"></div>
    

    You can use the following strategies (view all of this in this fiddle: http://jsfiddle.net/teddyrised/dL2wswfm/1/)


    The background image hack

    This is achieved by specifying multiple background images, which is supported in CSS3 and modern browsers.

    .chevron {
        background-image:
            linear-gradient(to bottom left, #ccc 0%, #ccc 50%, transparent 50%, transparent 100%),
            linear-gradient(to bottom right, #ccc 0%, #ccc 50%, transparent 50%, transparent 100%);
        background-position:
            bottom left,
            bottom right;
        background-repeat: no-repeat;
        background-size: 50% 100%;
        background-color: red;
        width: 100%;
        height: 50px;
    }
    

    The border hack

    While the border hack provides the best visual result, it is not possible to use percentage values for the left and right border widths — you will either have to use absolute values (px, em...) or relative values with respect to the viewport (vh, vw, vmin, vmax). This limits the application to divs that stretches to a known percentage of the viewport:

    .chevron {
        background-color: red;
        position: relative;
        width: 100%;
        height: 50px;
    }
    .chevron::before {
        box-sizing: border-box;
        position: absolute;
        top: 0;
        left: 0;
        right: 50%;
        bottom: 0;
        content: '';
        border-top: 50px solid #ccc;
        border-left: 50vw solid transparent;
    }
    .chevron::after {
        box-sizing: border-box;
        position: absolute;
        top: 0;
        left: 50%;
        right: 0;
        bottom: 0;
        content: '';
        border-top: 50px solid #ccc;
        border-right: 50vw solid transparent;
    }
    

    See fiddle here: http://jsfiddle.net/teddyrised/dL2wswfm/1/