Y a-t-il une façon CSS d'ajouter une flèche si un ul a un enfant ul?

ma structure de navigation ressemble à ceci:

<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>

je veux que tous les <li> 's qui ont une sous-navigation enfants d'avoir un peu Flèche vers le bas appliqué afin que les utilisateurs savent que cette page a des sous-pages.

est-il possible de détecter dans CSS pur si un <li> a des enfants de ul.children ? Dans mon exemple ci-dessus, la" Page avec des sous-pages "devrait avoir la flèche vers le bas et la" Page avec une autre sous-page " aussi bien.

en ce moment j'utilise jquery pour résoudre ce problème:

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

y a-t-il un moyen facile et pur CSS pour le faire?

Merci.

27
demandé sur Thom Smith 2011-03-12 11:44:20

10 réponses

c'est parfaitement faisable dans CSS --

votre structure est la suivante:

 <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>

votre CSS sera comme ceci ...

   //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: ''; }   

aller un peu plus loin, si vous voulez avoir un menu déroulant où il y a une flèche vers le bas sur les éléments de niveau supérieur et puis des flèches à droite pour les sous-menus, votre CSS ressemblerait à ceci

   // 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: ''; }

Voici un jsfiddle dans l'action http://jsfiddle.net/w9xnv/2 /

85
répondu David 2012-08-21 19:32:05

Vous pourrait faites ceci:

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

voici un exemple

Ce n'est pas prise en charge dans tous les navigateurs , voici une liste de soutien

MODIFIER

vient de réaliser que mon exemple ci-dessus sera défectueux, la flèche sera dans la mauvaise position. Encore si c'est un avenue vous souhaitez poursuivre la possibilité d'aligner la flèche correctement.

7
répondu lnrbob 2011-03-12 09:08:10

je pense que la meilleure façon serait d'ajouter une classe (ou cette Portée que vous utilisez) à ces li sur le serveur.

une autre solution, mais probablement pas facile et pas propre, est d'ajouter la flèche à tous les ul s et de les rendre seulement visibles (en utilisant css) EN ul.enfant. Vous pouvez ensuite essayer de positionner la flèche devant ou derrière la mère de li. Si cela dépendra de la conception.

1
répondu GolezTrol 2011-03-12 08:57:12

dans l'intérêt de la simplicité, voici la solution que j'aime utiliser:

  1. placez des étiquettes autour du nom de l'élément agissant comme un menu déroulant.

    <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. ajouter la flèche en utilisant 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*/
    }
    

Espérons que cela fonctionne pour vous! Je crois que c'est la méthode la plus simple que j'ai rencontré!

1
répondu Arcanewinds 2015-01-28 13:21:07

pour les futurs lecteurs! Je me demandais aussi, et puis compris sur mon propre

nous ne pouvons pas vérifier si element a des enfants, mais nous pouvons vérifier s'il est vide""

li:not(:emtpy):after {
    content: "V";
    color: black;
    position: relative;
    left: 120%;
    /* Well those styles are not best but you get the idea */
}
1
répondu 2015-06-11 20:26:24

vieille question mais c'est comme ça que je le ferais:

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

vous pouvez aussi le rendre plus joli comme ceci:

.menu li > a:not(:only-child):after { 
    content: '"151910920"a0"151910920"a0▼'; /* 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 */
}
1
répondu rotaercz 2017-01-12 22:31:34

il n'y a pas de "sélecteur parent" CSS.

Mais voici un code jQuery plus court:

$('.children').prev('li').append('<span class="dwn">▼</span>');

votre question est similaire à celle-ci:

sélecteur CSS complexe pour parent d'enfant actif

0
répondu ipim.com 2017-05-23 12:34:18

Pour menu vertical : ce js, fonctionne sur all = nav.vertical li

$("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>
0
répondu Farzin Seyfollahi 2012-05-27 21:40:35

par exemple

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

et le 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;
0
répondu Cristopher 2014-01-24 09:53:27

C'est juste un raffinement de rotaercz S réponse. Avec l'aide 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;
}
0
répondu TecBrat 2017-05-23 12:34:18