This may seem pretty basic, are you allowed to put a link inside of a link? See attached image below:

I'm trying to have the whole grey bar clickable to go somewhere, but if the user clicks the wheel or the move arrow, they are other links. See my current code:

<a href="#" class="sp_mngt_bar">
    <h1><?php echo $v; ?></h1>
    <a href="#" class="t_icons t_icons_settings sp_mngt_settings"></a>
    <a href="#" class="t_icons t_icons_move sp_mngt_move"></a>
</a>

Is this a good practice? Am I doing it wrong? How would you do this? Thanks for the help!

Solution 1

Straight from the W3C for HTML4:

12.2.2 Nested links are illegal

Links and anchors defined by the A element must not be nested; an A element must not contain any other A elements.

Since the DTD defines the LINK element to be empty, LINK elements may not be nested either.

HTML 5

And for HTML5 it is a little different.

You cannot have Interactive Content inside an A element. Interactive Content includes anchor tags.

Solution 2

To simply answer the question: No.

That being said, here's a pure html/css workaround:

https://codepen.io/pwkip/pen/oGMZjb

.block {
  position:relative;
}

.block .overlay {
  position:absolute;
  left:0; top:0; bottom:0; right:0;
}

.block .inner {
  position:relative;
  pointer-events: none;
  z-index: 1;
}

.block .inner a {
  pointer-events: all;
}
<div class="block">
  <a class="overlay" href="#overlay-link"></a>
  <div class="inner">
    This entire box is a hyperlink. (Kind of)<br><br><br><br>
    <a href="#inner-link">I'm a W3C compliant hyperlink inside that box</a>
  </div>
</div>

Solution 3

Wrap your nested link inside an object tag :

<a href="#" class="sp_mngt_bar">
    <h1><?php echo $v; ?></h1>
    <object><a href="#" class="t_icons t_icons_settings sp_mngt_settings"></a></object>
    <object><a href="#" class="t_icons t_icons_move sp_mngt_move"></a></object>
</a>

Solution 4

Although I totally agree with the selected answer and yes, you shouldn't have Interactive Content inside an A element, sometimes you may need a workaround to this.

Here's an example where you need to put an interactive element inside an A tag. That little close button on the top right.

Here's the HTML for this. (It's not the actual build, I made it a bit simpler)

    <a href="#">
        <span class="hide">X</span> <!-- THIS IS THE SMALL 'X' WHICH HIDES THE WHOLE BOX -->
        <img src="images/camera.svg" width="50" alt="Camera" />
        <em>
            Upload a profile picture
            <small>
                Here's the deal. Make your profile look awesome and even get 25 karma for it. We're not kidding.
            </small>
        </em>
        <strong>
            + 25 K
        </strong>
    </a>

So, basically we want to hide this box when the user clicks on the 'X'. Otherwise, just it should work like a simple A tag. Here's the jQuery which did the trick.

    $('.hide').click(function(e) {
            e.preventDefault();
            e.stopPropagation(); // THIS IS THE KEY PART
    
            // DO WHATEVER YOU WANT, I FADED OUT THE BOX FOR EXAMPLE
            $(this).parent().fadeOut(300);
    });

I hope this helps someone with the same problem. ;)

Solution 5

I would restyle it so that it is more like this format:

<div class="sp_mngt_bar">
    <h1><a href="#"<?php echo $v; ?></a></h1>
    <a href="#" class="t_icons t_icons_settings sp_mngt_settings"></a>
    <a href="#" class="t_icons t_icons_move sp_mngt_move"></a>
</a>

Solution 6

Nested links are illegal. To achieve the same behavior as with nested links you can do the following:

Use @mikevoermans HTML format as shown below and bind click event

<div class="sp_mngt_bar">
    <h1><a href="#"<?php echo $v; ?></a></h1>
    <a href="#" class="t_icons t_icons_settings sp_mngt_settings"></a>
    <a href="#" class="t_icons t_icons_move sp_mngt_move"></a> 
</div>

Your click event should look like this:

$(".sp_mngt_bar").bind("click", function(e) {   
    var target = $(e.target);
    if(target.has('.t_icons_settings') { //Do something for settings } 
    else if(target.has('.t_icons_move') { //Do something for move }
    else { //Do something for sp_mngt_bar
});

Solution 7

While technically not an answer to the question, another workaround is to bind the click event to a span or div:

<a href="outer-link">
  Outer Link
  <span class='inner-link'>Inner Link</span>
</a>

$('.inner-link').click(function (e) {
    // Prevent the click-through to the underlying anchor
    e.stopPropagation();

    // Go to a link
    window.location.href = 'page.html';
    // Or call a javascript method
    doSomething();

    return false;
});

Solution 8

One solution is to position a link absolutely inside of the parent link container:

<div style="position: relative">
  <a href="#">
    <h1><a href="#"<?php echo $v; ?></a></h1>
    <div id="placeholder" style="height: 24px">
  </a>
  <div style="position: absolute; bottom: 0">
    <a href="#"></a>
  </div>
</div>

Solution 9

@Jules answer, just shorter:

.parent {
  position:relative;
}

.overlay-link {
  position:absolute;
  inset: 0;
}

html:

<div class="parent">
    <a class="overlay-link" href="..."/>
    <div class="child">
                    
    </div>
</div>