Search code examples
csspseudo-class

CSS pseudo class. Dynamic height arrows


I have menu items which are to be styled as follows:

enter image description here

The arrow at the end I am achieving with an :after pesudo-class:

.ride-type-menu:after{
        content:"";
        border: 13px solid;
        border-color:  transparent #DBD7D7;
        border-right-color: transparent;
        right: -26px;
        top: 0;
        position: absolute;
        display: block;
    }

The issue I have is when these menu items stretch down onto multiple lines:

enter image description here

Can anyone think of a way (even with an image if necessary) that I can increase the height (keeping the width) of the arrow automatically based on the number of lines the menu item takes up to achieve something like this:

enter image description here


Solution

  • Here's one idea on how you could do this, use an SVG image for the li background, then resize it using the CSS background-size property. This works in IE 9, Firefox, Safari and Chrome however it looks a little bit funky in Opera (there maybe a fix?).

    First, you'll need the SVG XML, save the following in a new text file, save it as 'right-arrow.svg'

    SVG

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    
    <svg
       xmlns:dc="http://purl.org/dc/elements/1.1/"
       xmlns:cc="http://creativecommons.org/ns#"
       xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
       xmlns:svg="http://www.w3.org/2000/svg"
       xmlns="http://www.w3.org/2000/svg"
       version="1.1"
       width="152.18813"
       height="175.7317"
       id="svg2"
       preserveAspectRatio="none">
      <defs
         id="defs4" />
      <metadata
         id="metadata7">
        <rdf:RDF>
          <cc:Work
             rdf:about="">
            <dc:format>image/svg+xml</dc:format>
            <dc:type
               rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
            <dc:title></dc:title>
          </cc:Work>
        </rdf:RDF>
      </metadata>
      <g
         transform="translate(-37.842052,-201.63918)"
         id="layer1">
        <path
       d="m 37.842053,377.37089 -10e-7,-87.86586 0,-87.86585 76.094068,43.93293     76.09405,43.93293 -76.09406,43.93292 z"
           id="path2987"
           style="fill:#00f0ff;fill-opacity:1;stroke:none" />
      </g>
    </svg>
    

    Then use this:

    HTML

    <ul>
        <li>first</li>
        <li>first<br>second<br>third</li>
        <li>first<br>second</li>
    </ul>
    

    CSS

    ul { margin: 0; padding: 0; list-style-type: none; }
    
    li {
        margin-bottom: 5px;
        position:relative;
        width: 200px;
        background: url('right-arrow.svg') right center no-repeat;
        background-size: 15px 100%;
        padding: 15px;
    }
    
    li:after {
        content: ' ';
        display: block;
        position: absolute;
        top: 0; left: 0;
        width: 215px; /* (li width + padding) - background-size width */
        height: 100%;
        background-color: #00f0ff;
        z-index: -1;
    }
    

    Bit sloppy but you can refine this as you need, the idea is there.