I 've searched a lot on S.O. but I could not find any answer that works 100%.
My problem is that I have a card component in a NextJs application that is wrapped around a <Link>
tag. I also have one more <Link>
tag inside, 2 external links (<a>
tags) and a button. But none of these work. I have tried putting position: relative
to the buttons and anchor tags but it partialy solved the problem (I can navigate to the link ONLY if I use the middle click of my mouse, which opens the link to a new tab). I want to make it work such that any clicks will be registered.
Card Component
<Link href={`/${song.singer}/${song.title}`} passHref>
<div className={style.cardOutter}>
<div className={style.cardHeader} style={{ backgroundImage: `url(${sdDefault(song.thumbnail)})` }}></div>
<div className={style.cardBody}>
<p>{song.title}</p>
{song.fts !== '' ?
<div className={style.card_fts}>
<span>{song.fts}</span>
</div>
:
null
}
<div className={style.cardInfoCont}>
<small>[{song.lang}] {song.album} - {song.genre}</small>
</div>
</div>
<div className={style.cardButtons}>
<a href={`https://www.youtube.com/watch?v=${song.thumbnail}`} target='_blank' rel='noreferrer' title='Listen On YouTube'><YouTubSimpleIcon color='#ff0000' width={30} height={30} /></a>
<button disabled={!authContext.isAuth} title='Add To Favouarites'><HeartIcon color='#ff0000' width={30} height={30} /></button>
<a href={`https://open.spotify.com/${song.spotifyURL === undefined ? '' : song.spotifyURL}`} target='_blank' rel='noreferrer' title='Listen On Spotify'><SpotifySimpleIcon color='#1db954' width={30} height={30} /></a>
</div>
<div className={style.cardLyricsBtn}>
<Link href={`/${song.singer}`} passHref>
<button>
Check The Artist!
</button>
</Link>
</div>
</div>
</Link>
SCSS File
.cardOutter {
width: 250px;
height: fit-content;
border-radius: 5px;
margin: auto;
margin-top: 2rem;
background-color: $primaryBlack;
color: $lightWhite;
transition: transform 250ms linear;
-webkit-box-shadow: 0px 0px 8px 3px rgba(0, 0, 0, 0.7);
box-shadow: 0px 0px 8px 3px rgba(0, 0, 0, 0.7);
cursor: pointer;
.cardHeader {
@include mixins.d-flex(center, center, row);
width: 100%;
min-height: 100px;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
border-radius: 5px 5px 0 0;
}
.cardBody {
width: 100%;
padding: .5rem 1rem;
p {
width: 100%;
text-align: center;
font-size: 1.1rem;
font-weight: 500;
}
.card_fts {
width: 100%;
text-align: center;
font-size: 1rem;
font-weight: 400;
}
.cardInfoCont {
@include mixins.d-flex(center, center, row);
width: 100%;
margin-top: .4rem;
}
}
.cardButtons {
@include mixins.d-flex(center, space-around, row);
margin: .5rem 0;
padding-bottom: 1rem;
button {
@include mixins.naturalButton();
@include mixins.d-flex(center, center, row);
background-color: transparent;
width: 40px;
height: 40px;
border-radius: 50%;
position: relative;
z-index: 100;
}
a {
@include mixins.simpleAnchor();
@include mixins.d-flex(center, center, row);
background-color: transparent;
width: 40px;
height: 40px;
border-radius: 50%;
position: relative;
z-index: 100;
}
}
.cardLyricsBtn {
@include mixins.d-flex(center, center, row);
border-radius: 0 0 5px 5px;
button {
@include mixins.naturalButton();
@include mixins.d-flex(center, center, row);
font-size: 1.2rem;
font-weight: 500;
width: 100%;
padding: .5rem 0;
border-radius: 0 0 5px 5px;
transition: background 200ms linear;
}
a {
@include mixins.simpleAnchor();
@include mixins.d-flex(center, center, row);
font-size: 1.2rem;
font-weight: 500;
width: 100%;
padding: .5rem 0;
border-radius: 0 0 5px 5px;
}
}
}
CodePudding user response:
This issue is not really related to Next.js. You'd have the same issues with normal anchor tags because nesting links produces invalid HTML, though there are some workarounds like putting the nested link into an object
tag.
Other than that, you could try the following approaches:
- Handle either the container link or the nested links via an
onClick
handler instead of an anchor tag. - Don't nest your links in the HTML tree but instead make them siblings and align them using only CSS. You could use a
div
container and position all of your links withposition: absolute
inside that div.
In any case you will probably also need to look at event bubbling and add an onClick={e => e.stopPropagation()}
where necessary.