2011-03-12 37 views
27

Mi estructura de navegación se ve así:¿Hay alguna forma de CSS para agregar una flecha si un ul tiene un hijo ul?

<div class="menu"> 
    <ul> 
     <li><a href="#">Page 1</a></li> 
     <li><a href="#">Page with Subpages</a> 
      <ul class="children"> 
       <li><a href="#">Page with another subpage</a> 
        <ul class="children"> 
         <li><a href="#">subsubpage</a></li> 
        </ul> 
       </li> 
      </ul> 
     </li> 
     <li><a href="#">Page 3</a></li> 
     <li><a href="#">Page 4</a></li> 
    </ul> 
</div> 

Quiero que todos <li> 's que tienen un subnavegación hijos tengan una pequeña flecha hacia abajo que se aplica para que los usuarios conocer esta página tiene subpáginas.

¿Es posible detectar en css puro si un <li> tiene hijos de ul.children? En mi ejemplo anterior, la "Página con subpáginas" debe tener aplicada la flecha hacia abajo y la "Página con otra subpágina" también.

En este momento estoy usando jQuery para resolver este problema:

$(function() { 
    $('.menu a').each(function() { 
     if ($(this).parent('li').children('ul').size() > 0) { 
      $(this).append('<span class="dwn">▼</span>'); 
     }   
    }); 
}); 

¿Hay una manera fácil puro CSS para hacerlo?

Gracias.

Respuesta

1

Creo que la mejor manera sería agregar una clase (o ese span que estás usando) a esos li s en el servidor.

Otra solución, pero probablemente no es fácil y no está limpia, es agregar la flecha a todos ul sy solo hacerlos visibles (usando css) en ul.children. A continuación, puede intentar colocar la flecha delante o detrás de la li matriz. Si esto funcionará dependerá del diseño.

7

Usted podría hacer esto:

ul.children:before { 
    content: "▼"; 
} 

aquí es an example

Este no tiene soporte en todos los navegadores, here is a list of support

EDITAR

Acabo de darme cuenta de que mi ejemplo anterior será defectuoso, la flecha estará en la posición incorrecta. Aún así, si esta es una avenida en la que le gustaría seguir, existe la posibilidad de alinear la flecha correctamente.

+0

trabajó para mí, solo cambia: antes de: después de – Scott

0

Por menú vertical: este JS, funciona en todas = NAV.li verticales

$("nav.vertical li:has(ul)").find("a:first").append('<img src="" alt="" class="">'); 

<nav> 
    <ul> 
    <li><a href="">Page</a> 
     <ul class="children"> 
      <li><a href="">Post</a></li> 
     </ul> 
    </li> 
    </ul> 
</nav> 
84

Esto es perfectamente factible en CSS -

Su estructura es la siguiente:

<ul class="menu"> 
     <li> 
      <a href="#">Has arrow</a> 
      <ul><li><a href="#"></a></li></ul> 
     </li> 
     <li> 
      <a href="#">Has no arrow</a> 
     </li> 
    </ul> 

Su CSS será así -

//this adds an arrow to every link 
    .menu li > a:after { content: '>'; } 

    // this removes the arrow when the link is the only child 
    .menu li > a:only-child:after { content: ''; } 

Si lo toma un paso más allá, si desea tener un menú desplegable donde hay una flecha hacia abajo en los elementos de nivel superior y luego las flechas hacia la derecha para subme nus, el CSS se vería así

// set up the right arrows first 
    .menu li > a:after { content: '>'; } 

    //set up the downward arrow for top level items 
    .menu > li > a:after {content: 'v'; } 

    //clear the content if a is only child 
    .menu li > a:only-child:after {content: ''; } 

Aquí es una jsFiddle de él en acción - http://jsfiddle.net/w9xnv/2/

+0

Es CSS2 un solo hijo o CSS3? – crush

+2

Soporte de IE 9 y superior solo para el selector: only-child fyi – Relequestual

+0

@crush, only-child es CSS3 iirc. – Swivel

0

Por ejemplo

$(function() { 
$('.menu a').each(function() { 
    if ($(this).parent('li').children('ul').size() > 0) { 
     $(this).append('<span></span>'); 
    }   
    }); 
}); 

y el CSS

.menu li a span { 
display: -moz-inline-stack; 
display: inline-block; 
zoom: 1; 
*display: inline; 
vertical-align: middle; 
background: url(arrow.png) 0 0 no-repeat; 
width: 5px; 
height: 3px; 
margin-left: 5px; 
1

En el intereses de mantenerlo simple, aquí está la solución que me gusta usar:

  1. Coloque etiquetas alrededor del nombre del elemento que actúa como un menú desplegable.

    <div class="menu"> 
        <ul> 
         <li><a href="#"><span>Page with Subpages</span></a> 
          <ul class="children"> 
           <li><a href="#"><span>Page with another subpage</span></a> 
            <ul class="children"> 
             <li><a href="#">subsubpage</a></li> 
            </ul> 
           </li> 
          </ul> 
         </li> 
        </ul> 
    </div> 
    
  2. Añadir la flecha usando CSS:

    #menu span:after /* DropDown Arrow */ 
    { 
        border: 0.313em solid transparent; /* 5 pixels wide */ 
        border-bottom: none; /* helps the drop-down arrow stay in the vertical centre of the parent */ 
        border-top-color: #cfcfcf; /* colour of the drop-down arrow */ 
        content: ''; /* content of the arrow, you want to keep this empty */ 
        vertical-align: middle; 
        display: inline-block; 
        position: relative; 
        right: -0.313em; /* 5 pixels right of the menu text*/ 
    } 
    

Espero que esto funcione para usted! ¡Creo que es el método más simple que he encontrado!

1

¡Para futuros lectores! Me preguntaba demasiado y luego descubierto por mi cuenta

no podemos comprobar si el elemento tiene hijos, pero podemos comprobar si está vacío

li:not(:emtpy):after { 
    content: "V"; 
    color: black; 
    position: relative; 
    left: 120%; 
    /* Well those styles are not best but you get the idea */ 
} 
1

vieja pregunta, pero esta es la forma en que lo haría que:

.menu li > a:not(:only-child):after { content: '▼'; } 

también puede hacer que se vea más bonito de esta manera:

.menu li > a:not(:only-child):after { 
    content: '\00a0\00a0▼'; /* add a little spacing so it's not right next to the text */ 
    font-size: 0.8rem; /* adjust font size so it looks better */ 
    vertical-align: middle; /* vertical align to middle */ 
} 
+0

Esto funcionó muy bien para mí. Floté el triángulo sin embargo: '.menu li> a: not (: only-child): después del { contenido: '▼'; flotador: derecho; } ' – TecBrat

+0

Bueno, casi funcionó. Solo necesita reemplazar la flecha porque Firefox tiene un problema con ella. Puede ser la codificación de caracteres en la página donde lo estoy usando. – TecBrat

0

esto es sólo un refinamiento de rotaercz s respuesta. Con la ayuda de CSS Tricks

#cssmenu li > a:not(:only-child)::after { 
    content: ""; 
    width: 0; 
    height: 0; 
    border-left: 5px solid transparent; 
    border-right: 5px solid transparent; 
    border-top: 5px solid #fff; 
    float: right; 
} 
Cuestiones relacionadas