102
<html>
    <head>
    </head>
    <body>
        <div>
            <a href="http://www.google.com">
                <span>title<br></span>
                <span>description<br></span>
                <span>some url</span>
            </a>
        </div>
    </body>
</html>

I am pretty new to CSS, I have a simple case like the above. I would like to make the "title" and "some url" clickable but want to make description as non-clickable. Is there any way to do that by applying some CSS on the span so that whatever inside that span, it is not clickable. My constraint is that, I do not want to change the structure of the div, instead just applying css can we make a span which is inside an anchor tag, not clickable ?

D. Schreier
  • 1,700
  • 1
  • 22
  • 34
Shamik
  • 6,938
  • 11
  • 55
  • 72

8 Answers8

456

Actually, you can achieve this via CSS. There's an almost unknown css rule named pointer-events. The a element will still be clickable but your description span won't.

a span.description {
    pointer-events: none;
}

there are other values like: all, stroke, painted, etc.

ref: http://robertnyman.com/2010/03/22/css-pointer-events-to-allow-clicks-on-underlying-elements/

UPDATE: As of 2016, all browsers now accept it: http://caniuse.com/#search=pointer-events

UPDATE: As of 2022, browsers behavior may have changed, another option can be:

a {
    pointer-events: none;
}
a span:not(.description) {
    pointer-events: initial;
}
PIIANTOM
  • 1,311
  • 11
  • 20
FRAGA
  • 5,078
  • 1
  • 15
  • 13
1

Not with CSS. You could do it with JavaScript easily, though, by canceling the default event handling for those elements. In jQuery:

$('a span:nth-child(2)').click(function(event) { event.preventDefault(); });
bdukes
  • 152,002
  • 23
  • 148
  • 175
ceejayoz
  • 176,543
  • 40
  • 303
  • 368
  • 4
    Huh.Why every time somebody ask question related to html ,javascript etc ie client side... solution is Jquery. Question is not tagged with javascript nor with Jquery..I know you cant do this with css only but Jquery is not the solution. – Mohit Jain Jun 29 '10 at 19:36
  • 3
    jQuery is being used here as an /example/ only. That said, in a large percentage of practical situations jQuery is a very, very good choice. The example here is very well suited to jQuery. – Jon Cram Jun 29 '10 at 19:45
  • This solution could be good, but like that you prevent the click on all span inside a tag... and title span needs to be clear for click event! – Zuul Jun 29 '10 at 19:51
  • @Zuul As @Jon Cram stated, this is example code. He'd need to `class` the description `span` and target it specifically. – ceejayoz Jun 29 '10 at 19:53
  • @piemesons Those of us who work in jQuery tend to give examples in jQuery because it's a lot easier than the absurdities non-frameworked JS requires you to go through. – ceejayoz Jun 29 '10 at 19:54
  • @ceejayoz, Yes... correct, but a working example would help Shamik better ;) – Zuul Jun 29 '10 at 20:00
  • @piemesons I provided a vanilla example. – NateDSaint Jun 29 '10 at 20:57
  • @all Jquery fans.. I am not against of Jquery. @ceejayoz But you have to pay a cost for that ie 70kb for minified version of Jquery thats way you cant go for the Jquery solution everytime. You are thinking from developer's point of view.. Try to think from user point of view. – Mohit Jain Jun 29 '10 at 21:44
  • 2
    70kb once, if you set your server up right, and potentially not even once if you use Google's hosted version. – ceejayoz Jun 29 '10 at 21:51
  • Also, it's 24KB minified and gzipped, according to jQuery.com. – ceejayoz Jun 29 '10 at 22:16
  • Here's [a benchmark comparison](http://vanilla-js.com) between "vanilla JS" (the best JS framework ever ;) and a few of the popular DOM querying libraries, including jQuery. At the time these results were collected, jQuery was less than 3% the performance of equivalent by-ID lookup, and 0.2% the performance for collecting all elements by tag name. **0.2% (0.002x)** [You](https://github.com/nefe/You-Dont-Need-jQuery#readme) [really](https://blog.garstasio.com/you-dont-need-jquery/) [don't need jQuery](https://duckduckgo.com/?q=you+don%27t+need+jquery)! – amcgregor Oct 03 '19 at 13:56
  • @amcgregor Yes, in the last *nine years* since this question the browser/JS landscape has changed significantly. That shouldn't be a major surprise. – ceejayoz Oct 03 '19 at 14:08
  • @ceejayoz I'm… not actually sure of the point you are trying to convey. Are these results too old to be useful? (I admit; they're quite old.) [Not really](http://jsben.ch/Jx2GW) and [nope](http://jsben.ch/pJ1Sj), though admittedly with advances in JIT runtimes, the gap has narrowed—we've essentially patched browsers to make jQuery use hurt less, but it's still whipping yourself unnecessarily. (When I say "JS" I'm referring to 2009's ES5, not including ES6 in that. ES6 _truly_ makes jQuery obsolete for large chunks of the functionality it offers.) – amcgregor Oct 03 '19 at 14:20
  • @amcgregor My point is restarting a nearly decade-old conversation about this is kinda confusing to me. – ceejayoz Oct 03 '19 at 14:22
  • We can do it with CSS : pointer-events: none; – Donovan P Mar 24 '21 at 01:02
  • @DonovanP Doesn't seem to work in OP's case (disabling clicks on child elements of the ``). https://codepen.io/ceejayoz/pen/oNBXxYv – ceejayoz Mar 24 '21 at 01:28
0

CSS is used for applying styling i.e. the visual aspects of an interface.

That clicking an anchor element causes an action to be performed is a behavioural aspect of an interface, not a stylistic aspect.

You cannot achieve what you want using only CSS.

JavaScript is used for applying behaviours to an interface. You can use JavaScript to modify the behaviour of a link.

Jon Cram
  • 16,609
  • 24
  • 76
  • 107
  • It depends on a point of view. For me, property which defines if the button is enabled or disabled should be CSS/HTML part of work (stylistic aspect). The behavioural aspect should be only used to declare if the property exists or not (is active or not). – Kryszal Jul 24 '15 at 10:51
  • 1
    It's quite useful to be able to apply the rule pointer-events:none; with CSS when you want an element and all it's contents to be non-clickable, especially if you don't know or have control of the contents of the element (i.e. ad unit). This can be used in conjunction with javascript, for instance if you are changing view states and you want to make an element non-clickable for a time or under certain conditions. While perhaps not a perfect separation of presentation and business logic layers, in real-life applications it can be easiest and most maintainable solution. – Jeremy C Sep 23 '15 at 22:56
0

In response to piemesons rant against jQuery, a Vanilla JavaScript(TM) solution (tested on FF and IE):

Put this in a script tag after your markup is loaded (right before the close of the body tag) and you'll get a similar effect to the jQuery example.

a = document.getElementsByTagName('a');
for (var i = 0; i < a.length;i++) {
  a[i].getElementsByTagName('span')[1].onclick = function() { return false;};
}

This will disable the click on every 2nd span inside of an a tag. You could also check the innerHTML of each span for "description", or set an attribute or class and check that.

NateDSaint
  • 1,524
  • 2
  • 16
  • 35
  • -1 for a script-based solution. Spiders can detect CSS non-clickability, JS not so much. (E.g. spiders _will_ follow the links you have forbidden this way.) – amcgregor Jul 03 '19 at 14:49
  • I don't think it's necessary to -1 this: I admit that you can use CSS, this was meant as an alternative to jQuery or other non-vanilla JS approaches when CSS is not an option. – NateDSaint Jul 17 '19 at 18:51
  • For a tiny bit of ES6, which makes the entire thing 110% more readable: (but still absolutely terrible when `pointer-events` exists! Pro tip: doing things like this is a sign you need to re-think your approach.) `for ( let elem of document.getElementsByTagName('a') ) elem.addEventListener('click', e => { e.preventDefault(); });` – amcgregor Sep 25 '19 at 15:16
0

This is the simplest way I would have done it. Without bordering about CSS or javascript :

<html>
<head>
</head>
<body>
<div>
    <p>
       <a href="http://www.google.com">
          <span>title<br></span>
       </a>
          <span>description<br></span>
        <a href="http://www.google.com">
         <span>some url</span>
       </a> 
    </p>
</div>
</body>
</html>

You can replace the

tag with anything you want.

-1

Yes you can.... you can place something on top of the link element.

<!DOCTYPE html>
<html>
<head>
    <title>Yes you CAN</title>
    <style type="text/css">
        ul{
            width: 500px;
            border: 5px solid black; 
        }
        .product-type-simple {
            position: relative;
            height: 150px;
            width: 150px;
        }
        .product-type-simple:before{
            position: absolute;
            height: 100% ;
            width: 100% ;
            content: '';
            background: green;//for debugging purposes , remove this if you want to see whats behind
            z-index: 999999999999;
        }
    </style>
</head>
<body>
<ul>
    <li class='product-type-simple'>
        <a href="/link1">
            <img src="http://placehold.it/150x150">
        </a>
    </li>
    <li class='product-type-simple'>
        <a href="/link2">
            <img src="http://placehold.it/150x150">
        </a>
    </li>
</ul>
</body>
</html>

the magic sauce happens at product-type-simple:before class Whats happening here is that for each element that has class of product-type-simple you create something that has the width and height equal to that of the product-type-simple , then you increase its z-index to make sure it will place it self on top of the content of product-type-simple. You can toggle the background color if you want to see whats going on.

here is an example of the code https://jsfiddle.net/92qky63j/

Kevin Florenz Daus
  • 597
  • 3
  • 9
  • 23
-2

CSS relates to visual styling and not behaviour, so the answer is no really.

You could however either use javascript to modify the behaviour or change the styling of the span in question so that it doesn't have the pointy finger, underline, etc. Styling it like that will still leave it clickable.

Even better, change your markup so that it reflects what you want it to do.

FinnNk
  • 3,249
  • 23
  • 25
  • Trivial counter-point: tabbed-based interfaces (or even drop-down menus) using `:hover`, `:focus`, or `:focus-within`: user-managed state in CSS to build more complex behaviour. Second counter-point: scrolling behaviour **is** explicitly controlled by CSS, as scrolling is a visual behaviour. Given mouse cursor choice is a CSS property, choosing to respond to clicks or not makes sense to exist, which it does, ref: the top-voted answer: `pointer-events: none;` (sadly, not the picked answer) – amcgregor Jul 03 '19 at 14:56
-32

Using CSS you cannot, CSS will only change the appearance of the span. However you can do it without changing the structure of the div by adding an onclick handler to the span:

<html>
<head>
</head>
<body>
<div>
<a href="http://www.google.com">
  <span>title<br></span>
  <span onclick='return false;'>description<br></span>
  <span>some url</span>
</a>
</div>
</body>
</html>

You can then style it so that it looks un-clickable too:

<html>
<head>
     <style type='text/css'>
     a span.unclickable  { text-decoration: none; }
     a span.unclickable:hover { cursor: default; }
     </style>
</head>
<body>
<div>
<a href="http://www.google.com">
  <span>title<br></span>
  <span class='unclickable' onclick='return false;'>description<br></span>
  <span>some url</span>
</a>
</div>
</body>
</html>
Elf King
  • 1,189
  • 5
  • 7
  • 1
    Thanks for this feedback. On hover, the cursor is not changing to default *it stays as hand*, any idea how to fix that? – Shamik Jun 29 '10 at 21:27
  • 33
    With CSS you can using `pointer-events: none;`. See the answer below by FRAGA. I have personally tested it on Safari. – Samyak Bhuta Dec 02 '11 at 09:40
  • 3
    -1: It's not a good idea to put JS inline any more than putting CSS inline. You should be binding the event from an external JS file and preventing the default action. – zzzzBov May 13 '12 at 17:34
  • 18
    -1: incorrect: `pointer-events: none;` does exactly what was asked – cronoklee Nov 01 '12 at 18:39
  • 5
    It it possible indeed. `pointer-events` fixed my problem also – daminufe May 13 '15 at 12:50
  • @SamyakBhuta That’s true, but `pointer-events` are not supported by – jak.b Jul 06 '18 at 17:21
  • To be fair, this feature was fairly new and unknown by 2011, only chrome and Firefox supported it. don't blame him by not knowing this back then, `pointer-events` did not have so much diffusion as it does today. And he did try to answer to the best of his knowledge and skill, although it was a poor solution, it worked for the original poster IMHO – Wiston Coronell Mar 12 '21 at 16:17