Lien cliquable sur tout un élément avec liens internes

Appliquer une zone cliquable sur tout un bloc, tout en gardant la possibilité d'avoir d'autres liens au sein de ce bloc

by oilvier

HTML

<ul>
	<li>
		<a href="#" class="foo">
			<h2>Titre</h2>
			<p>Résumé de l'article.</p>
			<span>En savoir plus</span>
		</a>
	</li>
	<li>
		<a href="#" class="foo">
			<h2>Titre</h2>
			<p>Résumé de l'article.</p>
			<span>En savoir plus</span>
		</a>
	</li>
	<li>
		<a href="#" class="foo">
			<h2>Titre</h2>
			<p>Résumé de l'article. <a href="#">Avec un lien !</a></p>
			<span>En savoir plus</span>
		</a>
	</li>
</ul>

<ul>
	<li>
		<div class="foo">
			<h2>Titre</h2>
			<p>Résumé de l'article.</p>
			<a href="#" class="foo__more">En savoir plus</a>
		</div>
	</li>
	<li>
		<div class="foo">
			<h2>Titre</h2>
			<p>Résumé de l'article.</p>
			<a href="#" class="foo__more">En savoir plus</a>
		</div>
	</li>
	<li>
		<div class="foo">
			<h2>Titre</h2>
			<p>Résumé de l'article. <a href="#">Avec un lien !</a></p>
			<a href="#" class="foo__more">En savoir plus</a>
		</div>
	</li>
</ul>

<ul class="invisible-link">
	<li>
		<div class="foo">
			<h2>Titre</h2>
			<p>Résumé de l'article.</p>
			<a href="#" class="foo__more">En savoir plus</a>
		</div>
	</li>
	<li>
		<div class="foo">
			<h2>Titre</h2>
			<p>Résumé de l'article.</p>
			<a href="#" class="foo__more">En savoir plus</a>
		</div>
	</li>
	<li>
		<div class="foo">
			<h2>Titre</h2>
			<p>Résumé de l'article. <a href="#">Avec un lien !</a></p>
			<a href="#" class="foo__more">En savoir plus</a>
		</div>
	</li>
</ul>

SCSS

.foo {position: relative; display: block;
	// Les liens qui seront ajoutés dans le contenu ont le plus haut z-index
	a {position: relative; z-index:1;}
}

// On étend la surface du lien "En savoir plus" sur tout le conteneur
// 1. Pour que cette zone soit cliquable sur IE, il faut ajouter une couleur de fond transparent
// On choisit le code RGB du blanc car le noir est transformé en `background-color:transparent;` par la minification
// Et ça ne fonctionne plus
.foo__more {
	&:before {content:""; position: absolute; z-index:0; top:0; left:0; right:0; bottom:0; background-color:rgba(255,255,255,0); /* [1] */ z-index:0; overflow:hidden;}
	// On doit augmenter la spécifité du sélecteur pour prendre le pas sur `.foo a`
	@at-root a#{&} {position: static;}
}

// Si besoin de masquer l'intitulé "En savoir plus"
.invisible-link .foo__more {top:0; left:0; right:0; bottom:0; background-color:rgba(255,255,255,0); /* [1] */ overflow:hidden; text-indent:110%; white-space:nowrap;}
// On doit augmenter la spécifité du sélecteur pour prendre le pas sur `.foo a`
.invisible-link a.foo__more {position:absolute; z-index:0;}








// Styles pour l'exemple
body {font-family:sans-serif;}
a {color:inherit; text-decoration:none;}
ul {margin:0; padding:0; display:flex; list-style:none;
	& > li {flex:1 1 0%; margin:5px;}
}

.foo {border:2px solid firebrick; padding:5px;
	&:hover,
	&:focus {background-color:firebrick; color:white;}
	
	a {color:blue; 
		&:hover,
		&:focus {background-color:blue; color:white;}
	}
}
.foo__more {
	@at-root a#{&} {
		&:hover,
		&:focus {background-color:transparent;}
		&:focus {color:inherit;}
		&:focus:before {outline:2px solid firebrick; outline-offset:-2px;}
	}
}
.invisible-link .foo__more:before {display:none;}
.invisible-link a.foo__more {
	&:hover,
	&:focus {background-color:transparent; color:white;}
	&:focus {outline:2px solid firebrick; outline-offset:-2px;}
}