A layout featuring nested buttons and links within a card element, utilizing the power of Link in NextJs

After extensive searching on S.O., I have been unable to find a solution that works flawlessly. The issue at hand involves a card component in a NextJs application that is encompassed within a <Link> tag. Additionally, there is another <Link> tag nested inside, along with 2 external links (<a> tags) and a button. Regrettably, none of these elements are functioning as intended. Despite experimenting with adding position: relative to the buttons and anchor tags, the problem remains unresolved. The current workaround only allows for navigation to occur if using the middle mouse button to open the link in a new tab. I am seeking assistance with configuring it so that all clicks register properly.


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

Answer №1

This particular issue is not directly tied to Next.js. The challenges faced with nesting links would persist even with regular anchor tags, as it leads to the creation of invalid HTML structures. However, there are some potential workarounds available, such as placing the nested link within an object tag (as detailed in this resource: link).

In addition, you may consider exploring the following strategies:

  1. Implementing an onClick handler for either the parent container link or the nested links instead of relying on traditional anchor tags.
  2. Avoid structuring your links in a nested manner within the HTML tree; rather, treat them as siblings and manipulate their positioning using CSS exclusively. One approach could involve utilizing a div container and utilizing position: absolute to arrange all links inside that container.

In any scenario, it might also be necessary to delve into event bubbling and incorporate

onClick={e => e.stopPropagation()}
where applicable.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Assign a true or false value to every attribute of an object

Imagine we have a scenario with an interface like this: interface User { Id: number; FirstName: string; Lastname: string; Age: number; Type: string; } and a specific method for copying properties based on a flag. ...

HTML/JS Implementation: Back to Top Visual Element

- This website appears to be quite simple at first glance. However, I have encountered an issue where every time I scroll down and then click on the "About" menu option, it abruptly takes me back to the top of the page before displaying the section with a ...

Utilizing Material UI's React framework for maintaining uniform grid column heights

Take a look at the image provided for context. I am facing an issue with two div elements, where one should occupy 20% of the total browser height and the other should take up 80%. Currently, I am utilizing Material UI Grid for positioning, which looks lik ...

Adjusting font sizes for both multiline text within a <p> element and labels based on the number of lines

Whenever I have multiline paragraphs or labels, the font size seems to adjust depending on the number of lines. All I want is to keep the font size consistent regardless of the lines. The labels all have the same CSS styling and inheritance. Here is a vis ...

Achieving hover effects on <a> tags in CSS without using the href attribute

I'm looking to create a picture that changes when hovered over, and I've already achieved this using CSS by adjusting the z-index. However, I don't want users to be able to click on the image. To prevent this, I have removed the href from th ...

showing sections that collapse next to each other

I am currently designing a portfolio website using HTML, CSS, and vanilla JavaScript. I have implemented collapsing sections that expand when clicked on. However, the buttons for these sections are stacked vertically and I want to place them side by side. ...

Is it possible to automatically switch to a different route in a Next.js server component after a certain period of time?

Is it possible to achieve a similar function in an async server component: displaying the ui, waiting 3 seconds, and then redirecting to another route? In a client component, you can accomplish this using: useEffect(() => { function delay(ms: number) ...

Sticky sidebar navigation paired with a scrollable main content area and anchor links

Examining the fiddle reveals a straightforward page layout with a fixed menu on the left and scrollable content. I am looking to align the menu with the content without any blank space at the top that causes the menu to shift upwards while scrolling down. ...

Integrating Immutable.js with Angular 2

Looking to optimize performance in your Angular 2 app with immutable.js? Although my app is functioning properly, I am aiming to enhance its performance through optimization and refactoring. I recently discovered immutable.js and want to convert the data ...

Adjust the height of the following column to match the responsive height of the initial column

Those who have marked it as duplicate, I want to clarify that my question is not about making Bootstrap columns all the same height. Instead, I am focusing on responsive images while maintaining their aspect ratio, which is a different issue from simply en ...

Utilizing Jquery to implement active state and unique IDs during mouseover operation

I found this great example on Stack Overflow that demonstrates Jquery Show/Hide functionality when hovering over links. It works perfectly by showing the content of the next div when the corresponding link is hovered over. However, I'm facing an issu ...

What is the process for deleting an animation using JavaScript, and how can the background color be altered?

Two issues are currently troubling me. First off, I am facing a challenge with an animation feature that I need to modify within the "popup" class for a gallery section on a website. Currently, when users load the page, a square image and background start ...

Incorporate the xml2js JavaScript library with Angular 2 for enhanced functionality

I've been attempting to utilize xml2js as an XML parser within my Angular 2 (RC 1 with TypeScript) web application. Unfortunately, I've encountered several errors without finding a solution that works. Here is the detailed process I followed: ...

Affix Object to Bottom of Stationary Element

I have a header element that I want to remain fixed while scrolling. The scrollable area should be positioned directly after the fixed header, without using position: absolute and removing it from the document flow. To better illustrate the issue, I' ...

How can you make sure that a class property in TypeScript always matches the name of the class?

Click here for an example interface ICommandHandler<T> { type: string // how can we ensure that this equals T.name? handle(command: T): void; } interface ICommand {} class CreateTaskCommand implements ICommand{} class CreateTaskCommandHandler ...

Using MaterialUI to create a GridListTile with two IconButtons

I'm working with a GridListTile and trying to add a second button, but I'm having trouble getting both buttons to display. Even though I've attempted to include two ActionIcons, only one of them is showing up. Here's the code snippet: ...

After adding the exclude property to angular-cli.json, the spec files are now being linted

I am working on an Angular 4 application and have manually created two .spec files for a specific class. When I use the nglint command, it successfully lints these two files. However, the spec files that were automatically generated when I created a compon ...

Position divs to align text beside icons

I am currently working on a Bootstrap popover to display various pieces of information, each containing an icon and some text. Additionally, I am incorporating twig into this project. Here is the HTML structure: <span class="fa fa-user instructor-con ...

What is the sequence in which the browser handles CSS?

I have a specific class that is being styled in multiple places on my website. I am curious about the order in which the browser reads and applies these different styles. Can you explain this process to me? Inline Style <div class="yellowtag" sty ...

Tips for aligning inputs vertically and stretching them horizontally with bootstrap flex only

For a practice exercise, I want to achieve vertical left alignment and horizontal stretching of input fields using only Bootstrap Flex (or CSS3 flexbox), without relying on Bootstrap Grid or CSS3 grid layout. Here is the code snippet (also available on co ...