Puis-je imbriquer un élément <button> dans un <a> en utilisant HTML5?

145

Je fais ce qui suit:

 <a href="www.stackoverflow.com">
   <button disabled="disabled" >ABC</button>
 </a>  

Cela fonctionne bien mais j'obtiens une erreur de validation HTML5 qui dit que «l'élément 'bouton' ne doit pas être imbriqué dans l'élément 'un bouton'.

Quelqu'un peut-il me donner des conseils sur ce que je dois faire?

Marie
la source
8
Le validateur a déjà répondu à votre question pour vous, et vous a même expliqué pourquoi ce n'est pas valide dans ce message d'erreur.
Code inutile
1
Mais y a-t-il une alternative si je veux que Google puisse voir cela comme un lien. Comme exemple d'utilisation des boutons, j'ai des boutons appelés "<<" et ">>" pour l'enregistrement suivant et l'enregistrement précédent. Je pense que ce devraient être des boutons, mais la fonctionnalité est qu'ils renvoient à de nouvelles pages.
Marie
3
ma question est est-ce que c'est important ... si vous faites cette exception bien méritée.
Muhammad Umer
1
Si je mets <button> <a href="dsada.html"> Test </a> </button> cela ne fonctionne pas sur Internet Explorer 11 ou Firefox.
dutraveller

Réponses:

231

Non , ce n'est pas du HTML5 valide selon le document de spécification HTML5 du W3C :

Modèle de contenu: transparent , mais il ne doit y avoir aucun descendant de contenu interactif .

L'élément a peut être enroulé autour de paragraphes entiers, de listes, de tableaux, et ainsi de suite, même de sections entières, tant qu'il n'y a pas de contenu interactif à l'intérieur (par exemple des boutons ou d'autres liens).

En d'autres termes, vous pouvez imbriquer tous les éléments à l'intérieur d'un, <a>sauf les suivants:

  • <a>

  • <audio>(si l' attribut contrôles est présent)

  • <button>

  • <details>

  • <embed>

  • <iframe>

  • <img>(si l' attribut usemap est présent)

  • <input>(si l' attribut type n'est pas à l' état masqué )

  • <keygen>

  • <label>

  • <menu>(si l' attribut type est dans l' état de la barre d'outils )

  • <object>(si l' attribut usemap est présent)

  • <select>

  • <textarea>

  • <video>(si l' attribut contrôles est présent)


Si vous essayez d'avoir un bouton qui renvoie à quelque part, enveloppez ce bouton dans une <form>balise en tant que telle:

<form style="display: inline" action="http://example.com/" method="get">
  <button>Visit Website</button>
</form>

Cependant, si votre <button>balise est stylée en utilisant CSS et ne ressemble pas au widget du système ... Faites-vous une faveur, créez une nouvelle classe pour votre <a>balise et stylisez-la de la même manière.

Andrew Moore
la source
1
@Andrew Moore - Y a-t-il un autre moyen. Je pense que cela a posé des problèmes et c'est pourquoi il a été changé pour être à l'intérieur d'un lien <a>. Je ne sais pas quel était le problème, mais nous avons beaucoup de ces boutons comme celui-ci sur une page. Peut-être était-ce parce que nous voulions améliorer le référencement en utilisant des liens <a>.
Marie
2
@Marie: Il n'y a pas d'autre moyen que de styliser vos liens pour qu'ils ressemblent à des boutons.
Andrew Moore
3
user25 n'est pas préférable d'utiliser method = "post" car le navigateur demande de renvoyer un formulaire de publication lors de la navigation dans les deux sens. Comme GET est la méthode par défaut d'un formulaire, on peut laisser method = "get" par souci de concision.
Bijan
4
@AndrewMoore: styliser un lien pour qu'il ressemble à un bouton crée son propre ensemble de problèmes, comme l'accessibilité. Un bouton doit s'exécuter lorsqu'il a le focus et que vous appuyez sur la barre d'espace. Un lien ne le fait pas. Si vous vous souciez de l'ADA (ou si vous devez faire semblant de vous en soucier), cela peut vous mordre.
iconoclaste
2
Comme @jonaspas l'a suggéré, un <div>inside an <a>est absolument valide en HTML5: validator.w3.org/nu
...
43

Si vous utilisez Bootstrap 3 , cela fonctionne assez bien

<a href="#" class="btn btn-primary btn-lg active" role="button">Primary link</a>
<a href="#" class="btn btn-default btn-lg active" role="button">Link</a>
user2197018
la source
ne fonctionne pas bien avec une icône impressionnante de police de bouton rond à l'intérieur
Boîte
L'utilisation de class = 'btn btn-default' correspond aux autres boutons (MVC6).
crokusek
12

Non.

La solution suivante repose sur JavaScript.

<button type="button" onclick="location.href='http://www.stackoverflow.com'">ABC</button>

Si le bouton doit être placé dans un <form>avec existant method="post", assurez-vous que le bouton a l'attribut type="button"sinon le bouton soumettra l'opération POST. De cette façon, vous pouvez avoir un <form>qui contient un mélange de boutons d'opération GET et POST.

Peter Wilson
la source
onclick ne fonctionnera pas sur le protocole de fichier, donc il n'est pas utile pour la présentation statique, par exemple. dans ce cas, la propriété d'action est la voie à suivre.
netalex
1
Si le bouton est lié à une page, alors ce n'est pas un bouton, c'est une ancre
Capsule
@Capsule, il est si courant de voir ces jours-ci. Regardez simplement la page de destination de chaque cadre de développement Web existant. Je suis tout à fait pour l'argument puriste, mais même je dois admettre qu'un gros bouton rectangulaire a une meilleure, plus évidente, d'un lien, même s'il renvoie à une page au lieu d'initier une véritable action de formulaire.
TheDudeAprès le
En ce moment, j'ai un <a>intérieur <button>(avec le même href) comme sauvegarde si JS est désactivé, et dans six mois, je vais certainement être gêné d'avoir admis cela.
TheDudeAprès le
@TheDudeAbides Je ne parle pas de son aspect, je parle du balisage que vous souhaitez utiliser. Qu'est-ce qui vous empêche de styliser ce lien comme un gros bouton rectangulaire? À moins que votre site n'utilise aucun style du tout? btw la réponse ci-dessus celle que nous commentons en est un parfait exemple. C'est une balise d'ancrage, conçue comme un bouton.
Capsule du
10

Je viens de sauter dans le même problème et je l'ai résolu en remplaçant la balise «bouton» par la balise «span». Dans mon cas, j'utilise bootstrap. C'est à ça que ça ressemble:

<a href="#register"> 
    <span class="btn btn-default btn-lg">
        Subscribe
    </span>
</a> 
gobeltri
la source
4
Vous n'avez pas du tout besoin de la durée avec le bootstrap. Déplacez simplement toute la partie de la classe vers le <a> et vous aurez un bouton de lien. par exemple <a href="#register" class="btn btn-default btn-lg"> Abonnez-vous </a>
Ryan Buddicom
L'affiche originale a demandé s'il était possible de placer un bouton à l' intérieur d' une étiquette d'ancrage. La réponse acceptée note qu'il va à l'encontre des spécifications du W3C de placer un <a> dans un <a>. Je pense que c'est la raison pour laquelle golbeltri faisait la démonstration de styliser un <span> comme un bouton.
StackOverflowUser
Cela a du sens s'il y a un autre contenu à l'intérieur de <a>, qui fait partie du lien, mais qui n'a pas le style d'un bouton. Par exemple, tout clic dans une div(image, arrière-plan, texte, etc.) mène à un lien, mais seul l' spanaspect ressemble à un bouton.
Josiah
7

Ce serait vraiment bizarre si cela était valide, et je m'attendrais à ce que ce soit invalide. Que devrait signifier avoir un élément cliquable à l'intérieur d'un autre élément cliquable? De quoi s'agit-il - un bouton ou un lien?

Steve Jorgensen
la source
Merci Steve. C'était une méthode qui m'a été suggérée par un collaborateur. La méthode fonctionne. Y a-t-il une meilleure façon de faire cela?
Marie
1
@Marie Si vous voulez faire ressembler un lien à un bouton, il est facile d'utiliser des styles CSS pour le faire apparaître comme tel. Ajouter un style à la frontière similaire à ceci: border: 2px outset. Si vous voulez arrondir un peu les coins, vous pouvez également utiliser un rayon de bordure. Une simple <img>balise fonctionnerait bien aussi.
Code inutile
3

Une autre option consiste à utiliser l'attribut onclick du bouton:

<button disabled="disabled" onClick="location.href='www.stackoverflow.com'" >ABC</button>

Cela fonctionne, cependant, l'utilisateur ne verra pas le lien affiché au survol comme il le ferait s'il était à l'intérieur de l'élément.

LaserCat
la source
2

Ces jours-ci, même si la spécification ne le permet pas, il "semble" toujours fonctionner pour intégrer le bouton dans une <a href...><button ...></a>balise, FWIW ...

rogerdpack
la source
2
Cela fonctionne lorsque le <button>n'est pas contenu dans un fichier <form>. Cependant, dès que le bouton est contenu (par exemple, <form>...<a><button>) cela cesse de fonctionner, sauf si l' on désactive le gestionnaire au clic du bouton. C'est assez de girations pour justifier d'éviter ce scénario.
évêque
0

Vous pouvez ajouter une classe au bouton et mettre un script la redirigeant.

Je le fais de cette façon:

<button class='buttonClass'>button name</button>

<script>
$(".buttonClass').click(function(){
window.location.href = "http://stackoverflow.com";
});
</script>
divHelper11
la source
0

pourquoi pas..vous pouvez également intégrer une image sur un bouton

<FORM method = "POST" action = "https://stackoverflow.com"> 
    <button type="submit" name="Submit">
        <img src="img/Att_hack.png" alt="Text">
    </button>
</FORM> 
Tapasit Suesasiton
la source
2
Le problème est que <a> </a>, comme le PO le demandait à l'époque, est un peu restrictif dans ce qu'il permet d'être dans ses limites. Voir la question acceptée ici.
Thomas
-1

Il est illégal en HTML5 d'incorporer un élément de bouton dans un lien.

Mieux vaut utiliser CSS par défaut et: états actifs (pressés):

body{background-color:#F0F0F0} /* JUST TO MAKE THE BORDER STAND OUT */
a.Button{padding:.1em .4em;color:#0000D0;background-color:#E0E0E0;font:normal 80% sans-serif;font-weight:700;border:2px #606060 solid;text-decoration:none}
a.Button:not(:active){border-left-color:#FFFFFF;border-top-color:#FFFFFF}
a.Button:active{border-right-color:#FFFFFF;border-bottom-color:#FFFFFF}
<p><a class="Button" href="www.stackoverflow.com">Click me<a>

Patanjali
la source
-2

J'essaye vos solutions javascript mais, pour le travail, je dois insérer le e.preventDefault();dans ma fonction javascript.

<!-- Add your HTML !-->
<a id="id_primary_link" href="my_primary_link.php">
  <button onclick="my_trick_function('my_secondary_link.php')">
</a>


<!-- Add your javascript function !-->
<script>
function my_trick_function(secondary_link){
    $('#id_primary_link').click(function(e) {
        e.preventDefault();
        window.location.replace(secondary_link);
    });
}   
</script>   
Paolo Ferraris
la source
-3

Utiliser l'attribut formaction à l'intérieur du bouton

PS! Cela ne fonctionne que si votre bouton type = "soumettre"

<button type="submit" formaction="www.youraddress.com">Submit</button>
Moonfly
la source
vous devez également mettre le bouton dans une balise <form>.
denodster
-3

<a href="index.html">
  <button type="button">Submit</button>
</a>
Ou vous pouvez utiliser le script java dans le bouton comme:

<button type="submit" onclick="myFunction()">Submit</button>
<script>
  function myFunction() {
      var w = window.open(file:///E:/Aditya%20panchal/index.html);
    }
</script>

aditya panchal
la source
Le simple fait de devenir certains navigateurs le permettra, cela ne veut pas dire que c'est une bonne idée.
denodster