Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting up pure css arrows to menu with transparent or image background?

I am trying to apply a pure css arrow to my SELECTED link of horizontal and vertical menu but can't seem to figure out the outcome I wanted. Some similar solutions here at stackoverflow but it doesn't solve my issue.

UL has a border and that's where the problem is coming from... But I shouldn't remove the UL border.

FIDDLE HERE

<li class="selected"><a href="#">Arrow please</a></li>

Objective

ul.hor {
  border-bottom: 3px solid blue;
}
ul li {
  display: inline-block;
  position: relative;
}
ul li a {
  display: block;
  padding: 10px 15px;
}
ul li.selected a {
  color: green;
}
ul li.selected:after {
  content: "";
  width: 12px;
  height: 12px;
  position: absolute;
  background: #fff;
  border-top: 3px solid blue;
  border-right: 3px solid blue;
}
ul.hor li.selected:after {
  left: 0;
  right: 0;
  bottom: -8px;
  margin: 0 auto;
  -moz-transform: rotate(315deg);
  -webkit-transform: rotate(315deg);
  -ms-transform: rotate(315deg);
}
ul.ver li.selected:after {
  right: -8px;
  top: 50%;
  margin-top: -6px;
  -moz-transform: rotate(225deg);
  -webkit-transform: rotate(225deg);
  -ms-transform: rotate(225deg);
}
ul.ver {
  width: 200px;
  border-right: 3px solid blue;
}
ul.ver li {
  display: block;
}
ul.ver li a {
  display: block;
  padding: 10px 15px;
}
body {
  width: 90%;
  margin: 20px auto;
  background: rgb(229, 180, 230);
  background: -moz-linear-gradient(30deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
  background: -webkit-linear-gradient(30deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
  background: -o-linear-gradient(30deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
  background: -ms-linear-gradient(30deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
  background: linear-gradient(120deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
}
<ul class="hor">
  <li><a href="#">Lorem</a></li>
  <li><a href="#">Ipsum</a></li>
  <li class="selected"><a href="#">Sit amet</a></li>
  <li><a href="#">Consectetur</a></li>
</ul>
<br>
<ul class="ver">
  <li><a href="#">Lorem</a></li>
  <li><a href="#">Ipsum</a></li>
  <li class="selected"><a href="#">Sit amet</a></li>
  <li><a href="#">Consectetur</a></li>
</ul>
like image 338
wj R. Avatar asked Apr 06 '15 03:04

wj R.


2 Answers

This one is easier to position and has a perfect triangle. We are still using transform rotate but no need for transform skew. No need to calculate width as well. Fiddle here.

ul {
    overflow: hidden;
}
li {    
    display:inline-block;position: relative;
}
ul li a {
  display: block;padding:20px 15px;
}
ul li.selected a {
  color: green;
}
ul.hor li.selected:before,
ul.hor li.selected:after {
   content: "";
   bottom: 0;
   position: absolute;
   border-bottom:3px solid blue;
   width:9999px;
   margin:0 10px;left:50%;
}
ul.hor li.selected:after {
    left:auto;right:50%;
}
/*vertical menu starts*/
ul.ver {
  width: 200px;
}
ul.ver li {
  display: block;
}
ul.ver li a {
  padding:10px 15px;
}
ul.ver li.selected:before,
ul.ver li.selected:after {
   content: "";
   position: absolute;
   top:50%;
   right: 0;
   border-right:3px solid blue;
   height:9999px;
   margin:10px 0
}
ul.ver li.selected:after {
    top:auto;bottom:50%;
}

/*arrow starts*/
ul li.selected a:after {
    content: "";
    width: 15px;
    height: 15px;
    position: absolute;
    border: solid blue;
    border-width: 3px 3px 0 0;  
}

ul.hor li.selected a:after {
    top:100%;
    left: 0;
    right: 0;
    margin: -10px auto 0; 
    -moz-transform: rotate(315deg);
    -webkit-transform: rotate(315deg);
    -ms-transform: rotate(315deg);
}
ul.ver li.selected a:after {
    left:100%;
    margin-left:-10px;
    -moz-transform:rotate(225deg);
    -webkit-transform:rotate(225deg);
    -ms-transform:rotate(225deg);
}
body {
    width:90%;margin:20px auto;
    background: rgb(229, 180, 230);
background: -moz-linear-gradient(30deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
background: -webkit-linear-gradient(30deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
background: -o-linear-gradient(30deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
background: -ms-linear-gradient(30deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
background: linear-gradient(120deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
}
<ul class="hor">
	    <li><a href="#">Lorem</a></li>
	    <li class="selected"><a href="#">Ipsum</a></li>
	    <li><a href="#">Sit amet</a></li>
	    <li><a href="#">Consectetur</a></li>
	</ul>
<br>
	<ul class="ver">
	    <li class="selected"><a href="#">Lorem</a></li>
	    <li><a href="#">Ipsum</a></li>
	    <li><a href="#">Sit amet</a></li>
	    <li><a href="#">Consectetur</a></li>
	</ul>
like image 184
jamez88 Avatar answered Nov 15 '22 16:11

jamez88


One approach would be to use absolute positioning with pseudo elements on the selected element.

The arrow is made with borders and skewX() skewY() on the pesudo elements. Their with for the horizontal menu and the height for the vertical one are set to a high value and the overflow is hidden on the <ul> element :

ul {
  overflow: hidden;
}
ul li {
  position: relative;
  display: inline-block;
  text-align: center;
}
ul li a {
  display: block;
  padding: 10px 15px;
}
ul li.selected a {
  color: green;
}
.hor .selected:before, .hor .selected:after {
  content: '';
  position: absolute;
  bottom: 0;
  height: 7px;
  width: 9999px;
  border-style: solid;
  border-width: 0px 4px 3px;
  border-color: blue;
}
.hor .selected:before {
  right: 50%;
  margin-right: -2px;
  transform-origin: 100% 0;
  transform: skewX(-45deg);
}
.hor .selected:after {
  left: 50%;
  margin-left: -2px;
  transform-origin: 0 0;
  transform: skewX(45deg);
}
ul.ver {
  width: 200px;
}
ul.ver li {
  display: block;
}
ul.ver li a {
  display: block;
  padding: 10px 15px;
}
.ver .selected:before, .ver .selected:after {
  content: '';
  position: absolute;
  right: 0;
  height: 9999px;
  width: 7px;
  border-style: solid;
  border-width: 4px 3px 4px 0;
  border-color: blue;
}
.ver .selected:before {
  bottom: 50%;
  margin-bottom: -2px;
  transform-origin: 0 100%;
  transform: skewY(-45deg);
}
.ver .selected:after {
  top: 50%;
  margin-top: -2px;
  transform-origin: 0 0;
  transform: skewY(45deg);
}
body {
  width: 90%;
  margin: 20px auto;
  background: rgb(229, 180, 230);
  background: -moz-linear-gradient(30deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
  background: -webkit-linear-gradient(30deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
  background: -o-linear-gradient(30deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
  background: -ms-linear-gradient(30deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
  background: linear-gradient(120deg, rgb(229, 180, 230) 30%, rgb(90, 140, 250) 70%);
}
<ul class="hor">
  <li><a href="#">Lorem</a></li>
  <li><a href="#">Ipsum</a></li>
  <li class="selected"><a href="#">Sit amet</a></li>
  <li><a href="#">Consectetur</a></li>
</ul>
<br>
<ul class="ver">
  <li><a href="#">Lorem</a></li>
  <li><a href="#">Ipsum</a></li>
  <li class="selected"><a href="#">Sit amet</a></li>
  <li><a href="#">Consectetur</a></li>
</ul>
like image 42
web-tiki Avatar answered Nov 15 '22 15:11

web-tiki