Creating a funnel stack template using native CSS and HTML

I want to show the data as a funnel stack, as shown below.

enter image description here

I managed to create a cone using borders, for example:

<div class="taper"></div> 

and using the following CSS:

 .taper { width: 200px; height: 0px; border-color: lightgray transparent; border-style: solid; border-width: 50px 25px 0 25px; } 

Of course, the idea would be to wrap this div.taper in a container, add other elements and put them as needed, work a little, but doable.

However, I don't necessarily know how many lines (levels, 7 in this example) will be needed, and I really don't want to do a lot of math to determine the width of each cone, etc.

If there is a more bulletproof way to do this?

I don’t want to use a JavaScript / jQuery-based solution (trying to keep this easy) and would prefer to avoid background images (maybe I would like to drop / adjust colors later and not want to worry about image files)

Link to the script: http://jsfiddle.net/audetwebdesign/fBax3/

Browser support: Modern browsers are fine, inherited support if it gets worse.

+6
source share
5 answers

TL DR : see example at http://jsfiddle.net/97Yr6/


The way to create a funnel stack consists of pseudo-elements: with this basic markup

 <ul> <li>1,234,567,890 <span>Tooltip: 0</span></li> <li>234,567,890 <span>Tooltip: 0</span></li> <li>23,456,789</li> <li>2,345,678 <span>Tooltip: 0</span></li> <li>234,567</li> <li>23,567 <span>Tooltip: 0</span></li> <li>4,567<span>Tooltip: 0</span></li> <li>789</li> <li>23 <span>Tooltip: 0</span></li> <li>4 <span>Tooltip: 0</span></li> </ul> 

we could create a funnel using borders, so we can draw some kind of trapezoid as a background like this:

 ul { position: relative; overflow: hidden; font: 14px Arial; margin: 0; padding: 0; list-style: none; text-align: center; } ul:before { content: ""; position: absolute; z-index: -1; left: 50%; margin-left: -120px; width: 0; border-top: 800px solid #ccc; border-left: 120px solid #fff; border-right: 120px solid #fff; } 

<ul> is 100% wide, so we can give it text-align: center , and all the amounts will be centered correctly

Then the space between the elements could be obtained with pseudo-elements again:

 li:after,li:before { content: ""; display: block; height: 0.4em; background: #fff; width: 100%; } li:before { border-top: 1px dotted #ccc } li:first-child:before { border: 0; } 

while the tooltip text can be positioned ( position: relative must be set for <li> ), trying to set the left and margin-left properties correctly (especially for lower screen resolution, but you can use media queries for this purpose) , eg

 li span { position: absolute; left: 60%; white-space: nowrap; margin-left: 100px; } li:nth-child(2) span { left: 59%; } li:nth-child(3) span { left: 58% } li:nth-child(4) span { left: 57% } li:nth-child(5) span { left: 56% } li:nth-child(6) span { left: 55% } li:nth-child(7) span { left: 54% } li:nth-child(8) span { left: 53% } li:nth-child(9) span { left: 52% } li:nth-child(10) span { left: 51% } 

basically this example can even work on IE8 if you change each :nth-child with an adjacency selector (e.g. li + li + li + ... + span )

Hope this can be helpful.

+3
source

For those who are looking for a funnel with different colors for each layer on the stack:

enter image description here

http://jsfiddle.net/D9GLr/

HTML:

 <ul> <li>1,234,567,890</li> <li>234,567,890</li> <li>23,456,789</li> <li>2,345,678</li> <li>234,567</li> </ul> 

CSS

 ul { margin: 0 200px; padding: 0; list-style: none; text-align: center; } li { font-size:14px; line-height:30px; height:30px; width:200px; position:relative; background:#ccc; border-bottom:1px solid #fff; } li:before { content: ""; position: absolute; z-index: 10; left: 0%; margin-left: -30px; width:30px; border-top: 30px solid #ccc; border-left: 30px solid transparent; } li:after { content: ""; position: absolute; z-index: 10; right: 0%; margin-left: 30px; width:30px; border-top: 30px solid #ccc; border-right: 30px solid transparent; } li:nth-child(1) { background:#ddd; } li:nth-child(1):before, li:nth-child(1):after { border-top-color:#ddd; } li:nth-child(1):before { width:200px; margin-left: -200px; } li:nth-child(1):after { width:200px; margin-right:-200px; } li:nth-child(2) { background:#bbb; } li:nth-child(2):before,li:nth-child(2):after { border-top-color:#bbb; } li:nth-child(2):before { width:170px; margin-left: -170px; } li:nth-child(2):after { width:170px; margin-right:-170px; } li:nth-child(3) { background:#999; } li:nth-child(3):before, li:nth-child(3):after { border-top-color:#999; } li:nth-child(3):before { width:140px; margin-left: -140px; } li:nth-child(3):after { width:140px; margin-right:-140px; } li:nth-child(4) { background:#777; } li:nth-child(4):before, li:nth-child(4):after { border-top-color:#777; } li:nth-child(4):before { width:110px; margin-left: -110px; } li:nth-child(4):after { width:110px; margin-right:-110px; } li:nth-child(5) { background:#555; } li:nth-child(5):before, li:nth-child(5):after { border-top-color:#555; } li:nth-child(5):before { width:80px; margin-left: -80px; } li:nth-child(5):after { width:80px; margin-right:-80px; } 
+2
source

Ryan

Thanks for your sample code! I took your example and modified it a bit to reflect my project needs. Maybe someone will find this useful.

 body { font-family: Lato, Arial, Helvetica, sans-serif; } .center-text { text-align: center; margin: 0px auto; } .funnel { width: 750px; margin: 0 auto; } ul.one { margin: 40px 278px; padding: 0; list-style: none; text-align: center; } .one .funnel-top { position: absolute; top: -7px; left: -199px; z-index: 20; width: 599px; height: 14px; background: #919eb1; border-radius: 100%; } .one .funnel-bottom { position: absolute; bottom: -7px; left: -20px; z-index: 20; width: 240px; height: 16px; background: #273445; border-radius: 100%; } .one li { font-size: 16px; line-height: 70px; height: 70px; width: 200px; position: relative; background: #ccc; color: #ffffff; font-weight: bold; } .one li span { background: rgba(255, 255, 255, 0.3); padding: 5px 8px; border-radius: 4px; margin-left: 15px; } .one li:before { content: ""; position: absolute; z-index: 10; left: 0%; margin-left: -30px; width: 30px; border-top: 70px solid #ccc; border-left: 30px solid transparent; } .one li:after { content: ""; position: absolute; z-index: 10; right: 0%; margin-left: 30px; width: 30px; border-top: 70px solid #ccc; border-right: 30px solid transparent; } .one li:nth-child(1) { background: #919eb1; } .one li:nth-child(1):before, .one li:nth-child(1):after { border-top-color: #919eb1; } .one li:nth-child(1):before { width: 200px; margin-left: -200px; } .one li:nth-child(1):after { width: 200px; margin-right: -200px; } .one li:nth-child(2) { background: #8491a5; } .one li:nth-child(2):before, .one li:nth-child(2):after { border-top-color: #8491a5; } .one li:nth-child(2):before { width: 170px; margin-left: -170px; } .one li:nth-child(2):after { width: 170px; margin-right: -170px; } .one li:nth-child(3) { background: #778599; } .one li:nth-child(3):before, .one li:nth-child(3):after { border-top-color: #778599; } .one li:nth-child(3):before { width: 140px; margin-left: -140px; } .one li:nth-child(3):after { width: 140px; margin-right: -140px; } .one li:nth-child(4) { background: #6d7b8f; } .one li:nth-child(4):before, .one li:nth-child(4):after { border-top-color: #6d7b8f; } .one li:nth-child(4):before { width: 110px; margin-left: -110px; } .one li:nth-child(4):after { width: 110px; margin-right: -110px; } .one li:nth-child(5) { background: #606f84; } .one li:nth-child(5):before, .one li:nth-child(5):after { border-top-color: #606f84; } .one li:nth-child(5):before { width: 80px; margin-left: -80px; } .one li:nth-child(5):after { width: 80px; margin-right: -80px; } .one li:nth-child(6) { background: #536075; } .one li:nth-child(6):before, .one li:nth-child(6):after { border-top-color: #536075; } .one li:nth-child(6):before { width: 50px; margin-left: -50px; } .one li:nth-child(6):after { width: 50px; margin-right: -50px; } ul.two { margin: 40px 278px; padding: 0; list-style: none; text-align: center; } .two .funnel-top { position: absolute; top: -7px; left: -199px; z-index: 20; width: 599px; height: 14px; background: #1b99e6; border-radius: 100%; } .two .funnel-bottom { position: absolute; bottom: -7px; left: -20px; z-index: 20; width: 240px; height: 16px; background: #003352; border-radius: 100%; } .two li { font-size: 16px; line-height: 70px; height: 70px; width: 200px; position: relative; background: #ccc; color: #ffffff; font-weight: bold; } .two li span { background: rgba(255, 255, 255, 0.3); padding: 5px 8px; border-radius: 4px; margin-left: 15px; } .two li:before { content: ""; position: absolute; z-index: 10; left: 0%; margin-left: -30px; width: 30px; border-top: 70px solid #ccc; border-left: 30px solid transparent; } .two li:after { content: ""; position: absolute; z-index: 10; right: 0%; margin-left: 30px; width: 30px; border-top: 70px solid #ccc; border-right: 30px solid transparent; } .two li:nth-child(1) { background: #1b99e6; } .two li:nth-child(1):before, .two li:nth-child(1):after { border-top-color: #1b99e6; } .two li:nth-child(1):before { width: 200px; margin-left: -200px; } .two li:nth-child(1):after { width: 200px; margin-right: -200px; } .two li:nth-child(2) { background: #148ad3; } .two li:nth-child(2):before, .two li:nth-child(2):after { border-top-color: #148ad3; } .two li:nth-child(2):before { width: 170px; margin-left: -170px; } .two li:nth-child(2):after { width: 170px; margin-right: -170px; } .two li:nth-child(3) { background: #117fc3; } .two li:nth-child(3):before, .two li:nth-child(3):after { border-top-color: #117fc3; } .two li:nth-child(3):before { width: 140px; margin-left: -140px; } .two li:nth-child(3):after { width: 140px; margin-right: -140px; } .two li:nth-child(4) { background: #0b75b6; } .two li:nth-child(4):before, .two li:nth-child(4):after { border-top-color: #0b75b6; } .two li:nth-child(4):before { width: 110px; margin-left: -110px; } .two li:nth-child(4):after { width: 110px; margin-right: -110px; } .two li:nth-child(5) { background: #006bac; } .two li:nth-child(5):before, .two li:nth-child(5):after { border-top-color: #006bac; } .two li:nth-child(5):before { width: 80px; margin-left: -80px; } .two li:nth-child(5):after { width: 80px; margin-right: -80px; } .two li:nth-child(6) { background: #005f98; } .two li:nth-child(6):before, .two li:nth-child(6):after { border-top-color: #005f98; } .two li:nth-child(6):before { width: 50px; margin-left: -50px; } .two li:nth-child(6):after { width: 50px; margin-right: -50px; } 
 <br /> <div class="funnel leads estimated"> <h2 class="center-text">Estimated 100 Day Lead Conversion</h2> <ul class="one"> <li> <div class="funnel-top"></div> 1574<span>Contacts</span> </li> <li>203<span>MQL2</span> </li> <li>112<span>MQL2</span> </li> <li>57<span>SAL</span> </li> <li>11<span>SQL</span> </li> <li> <div class="funnel-bottom"></div> 4<span>Wins</span> </li> </ul> </div> <div class="funnel leads estimated"> <h2 class="center-text">Actual 100 Day Lead Conversion</h2> <ul class="two"> <li> <div class="funnel-top"></div> 1574<span>Contacts</span> </li> <li>203<span>MQL2</span> </li> <li>112<span>MQL2</span> </li> <li>57<span>SAL</span> </li> <li>11<span>SQL</span> </li> <li> <div class="funnel-bottom"></div> 4<span>Wins</span> </li> </ul> </div> 

View in JSFiddle

+2
source

I like the approach of dividing it into multiple divs. See code here

I need to add the code like this:

 <div class="cont"> <div class="taper-left"></div> <div class="taper-center">123,456,789</div> <div class="taper-right"></div> </div> 

and CSS:

 .taper-right { width: 25px; height: 0px; border-color: lightgray transparent; border-style: solid; border-width: 50px 25px 0 0px; float: left; } .taper-left { width: 25px; height: 0px; border-color: lightgray transparent; border-style: solid; border-width: 50px 0px 0px 25px; float: left; } .taper-center { width: 200px; height: 34px; border-color: lightgray transparent; border-style: solid; background-color: lightgray transparent; background-color: lightgray; float: left; text-align: center; padding-top: 10px; } 
+1
source

Here is another example: this version is a bit more responsive: https://jsfiddle.net/ehynds/j3fL6hof

 .funnel { list-style-type: none; margin: 0; padding: 0; text-align: center; color: #fff; background-color: #fff; } li { padding: 10px 5px; margin: 0; background-color: #409ca9; margin-bottom: 5px; position: relative; overflow: hidden; } div:last-child { font-size: 36px } li:last-child { background-color: #a5c13f; } li:before, li:after { content: ''; position: absolute; top: 0; height: 0; border-bottom: 90px solid #fff; } li:before { left: 0; border-right: 27px solid transparent; border-left: 0; } li:after { right: 0; border-left: 27px solid transparent; border-right: 0; } li:nth-child(1):before, li:nth-child(1):after { width: 0; } li:nth-child(2):before, li:nth-child(2):after { width: 25px; } li:nth-child(3):before, li:nth-child(3):after { width: 50px; } li:nth-child(4):before, li:nth-child(4):after { width: 75px; height: 100%; border: 0; background-color: #fff; } 
 <ul class="funnel"> <li> <div>First Segment</div> <div>12,345</div> </li> <li> <div>Second Segment</div> <div>2,345</div> </li> <li> <div>Third Segment</div> <div>345</div> </li> <li> <div>Fourth Segment</div> <div>45</div> </li> </ul> 
0
source

Source: https://habr.com/ru/post/944517/


All Articles