1

I am trying to make a mobile version of a menu. So I have a list of item. The li with class nav-current is only displayed.With the help of pseudo :after I create an arrow after the link of that li. I try to display all the li items when the arrow is clicked.

My html :

<ul class="top-nav">
  <li>
    <a href=#>Textbla</a>
  </li>
  <li class="nav-current">
    <a href=#>Textlpops</a>
  </li>
  <li>
    <a href=#>Google Res</a>
  </li>
</ul> 

and my sassy css:

$depends:none;

  .top-nav { 
    float: none; 
    margin: 10px;
    li,li.user-tools {

    display:$depends;

    float:none!important;
    border-bottom: 1px solid #666;
    &:last-child {
     border-bottom:0 none;
    }
    &.nav-current {
     display:block;
     border-bottom:0 none;
     a:after {
       content:'arrow';
       color:#1a1a1a;
       position:absolute;
       top:10px;
       right:20px;
       height:12px;
       background: transparent url(../images/custom/arrow_down.png) no-repeat left top;
      }

     a:target:after {
       $depends:block;
     }

     }
   }   
}  

I don't want to use any javascript, so I search for an only css solution. Can this be done in sass? Or is there any css3 trick that I could take advantage of and make that happen?

ScottS
  • 71,703
  • 13
  • 126
  • 146
nasia
  • 27
  • 1
  • 9

1 Answers1

1

The target selector does not work the way you are expecting I think. What you describe is, to my knowledge, not possible in css.

New Answer

I reread your question and realized you were seeking this for mobile browsers. They may not be recognizing pointer-events either. This new solution does not rely on pointer-events except as an enhancement, but does require a bit more mark up. So far I have tested in FF, Chrome, and IE8/9, and it works well. (I'm curious if my zero opacity on the hover-shield may need to be 0.01 in some browsers). You'll have to test your mobile application.

HTML

<div class="hidden-nav">  
    <div class="nav-expander"></div>
    <div class="hover-shield"></div>  
    <ul class="top-nav">
      <li>
        <a href=#>Textlinks Adv</a>
      </li>
      <li class="nav-current">
        <a href=#>Textlinks Publ</a>
      </li>
      <li>
        <a href=#>Google Shopping</a>
      </li>
    </ul>
</div>

CSS

.hidden-nav {
    position: relative; 
    display: inline-block;
}

.nav-expander { /* the activator arrow container */
    width: 16px;
    height: 8px;
    position: absolute;
    top: 5px;
    right: 2px;
    z-index: 4;
}

.nav-expander:before { /* the activator arrow */
    content: '';
    display: block;
    width: 0;
    height: 0;
    border-left: 8px solid transparent;
    border-right: 8px solid transparent;
    border-top: 8px solid blue;
    position: absolute;
    top: 0;
    left: 0;
}

.hover-shield { /* keep activation by the arrow only */
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 2;
    background-color: white; /* needs background to act as hover shield */
    filter: alpha(opacity=0); /* no opacity needed */
    -moz-opacity: 0;
    opacity: 0;
}

.nav-expander:hover + .hover-shield {
    z-index: 0;
}

.top-nav {
    padding-right: 20px; /* make space for arrow */
    background-color: yellow;
    position: relative;    
    z-index: 1;
}

.top-nav:hover {
    z-index: 3;
}

.top-nav li {
    display: block; /*not "none" as we want widest li to size the nav*/
    visibility: hidden;
    height: 0; 
    white-space: nowrap; /*keep the link text in one line*/
}

.top-nav .nav-current {
    visibility: visible; 
    height: auto;
    pointer-events: none; /* for browsers that recognize it, the user is prevented from reclicking the page they are on */
}

.nav-expander:hover ~ .top-nav,
.top-nav:hover {
    height: auto; /*once triggered, let it be its height*/
}

/*show the nav if expander is hovered, or once that is done, the nave itself is hovered */
.nav-expander:hover ~ .top-nav li,
.top-nav:hover li {
    visibility: visible;
    height: auto;
}

Original Answer

However, I have worked up a pure css solution using hover on the arrow that works great in FF and Chrome (tested), works okay in IE8/9 (it does not recognize the pointer-events property on the nav-current, so it opens nav on hover of the nav-current); IE7 works like IE8/9 only without the arrow since :after is unrecognized.

One extra li is needed.

HTML

<ul class="top-nav">
  <li class="nav-expander"></li>  
  <li>
    <a href=#>Textlinks Adv</a>
  </li>
  <li class="nav-current">
    <a href=#>Textlinks Publ</a>
  </li>
  <li>
    <a href=#>Google Shopping</a>
  </li>
</ul>

CSS

.top-nav {
    float: left; /*fit to width of longest li*/
    padding-right: 20px; /*make space for arrow*/
    position: relative;
    background-color: yellow;
    height: 0; /*do not want expand on hover of nav-current*/
}
.top-nav li {
    display: block; /*not "none" as we want widest li to size the nav*/
    visibility: hidden;
    height: 0;
    white-space: nowrap; /*keep the link text in one line*/
    position: relative;
}
.top-nav .nav-current {
    visibility: visible;
    height: auto;
    z-index; 0;
    pointer-events: none; /*don't want hover on this to open nav*/
    background: inherit; /*show background to collapsed nav*/
}

.nav-current:after { /*fake background to collapsed nav*/
    content: '';
    position: absolute;
    width: 20px; /*= top-nav right padding*/
    top: 0;
    bottom: 0;
    left: 100%;
    background: inherit;
}
.nav-current a {
    color: red;
}
.top-nav a:hover {
    color: #555555;
}
.top-nav .nav-expander {
    visibility: visible;
    display: block;
    position: absolute;
    top: 0;
    right: 0;
    z-index: 1; /*cover nav-current when open*/
}

.top-nav .nav-expander:hover {
    left: 0; /*these cause coverage of nav-current on expansion*/
    bottom: 0;
}

.top-nav:hover {
    height: auto; /*once triggered, let it be its height*/
}

.nav-expander:after { /*the activator arrow*/
    content: '';
    display: block;
    width: 0;
    height: 0;
    border-left: 8px solid transparent;
    border-right: 8px solid transparent;
    border-top: 8px solid blue;
    position: absolute;
    top: 5px;
    right: 2px;
}

/*show the nav if expander is hovered, or once that is done, any li is hovered*/
.top-nav:hover li,
.nav-expander:hover ~ li {
    visibility: visible;
    height: auto;
    z-index: 2;
}

/*keeps z-index 0 on current; would use the :not(nav-current) selector to the above code, but IE8 does not recognize that*/
.top-nav:hover li.nav-current,
.nav-expander:hover ~ li.nav-current {
    z-index: 0;
}
ScottS
  • 71,703
  • 13
  • 126
  • 146
  • Thank you very much for sharing your work around. It's really nice and useful. My problem is that the nav appears on hover of the arrow but also on hover of the current li item.Shouldn't pointer-events prevent that?How can we limit the functionality on the arrow hover? – nasia Apr 05 '12 at 08:28
  • @nasia--as I mentioned in my answer, IE9 and below do not recognize `pointer-events` (I haven't checked whether that will be true of IE10 or not). So that is the behavior IE will have unless you implement some javascript to resolve it. – ScottS Apr 05 '12 at 09:51
  • Sorry for not giving you details. I have this problem on all browsers (latest versions),not only IE. – nasia Apr 05 '12 at 10:02
  • @nasia--Firefox 11 and Chrome 18 are working fine for me, so I don't know why you are having issues with it. [I don't know how many browsers it actually works on otherwise.](https://developer.mozilla.org/en/CSS/pointer-events) I have a thought about perhaps a slightly different solution to make it work more cross-browser but I don't know if I will be able to work on it until tomorrow. – ScottS Apr 05 '12 at 11:13
  • @ScottS- Sorry for taking too long to answer (Easter) and thank you for spending time to improve your answer and help me out.The second version is much better. The only problem I have is that I can't click anymore on the links of the menu. It seems like .nav-expander:hover + .hover-shield { z-index: 0; } doesn't work. Any ideas? – nasia Apr 19 '12 at 08:44
  • @ScottS- Don't pay attention to last comment.The only problem I have is that menu doesn't remain open if move mouse away from the arrow . It seems like .top-nav:hover { z-index: 3; } doesn't work.See [here](http://jsfiddle.net/GCvhA/11/) – nasia Apr 19 '12 at 13:42
  • 1
    @nasia--you forgot the `position: relative;` on `.top-nav`, so the `z-index` was being ignored. [Here is the fixed code.](http://jsfiddle.net/GCvhA/12/) – ScottS Apr 19 '12 at 22:28