Preventing an image from being draggable or selectable without using JS

CssHtmlFirefoxDraggable

Css Problem Overview


Does anyone know of a way to make an image not draggable and not selectable -- at the same time -- in Firefox, without resorting to Javascript? Seems trivial, but here's the issue:

  1. Can be dragged and highlighted in Firefox:

  2. So we add this, but image can still be highlighted while dragging:

  3. So we add this, to fix the highlighting issue, but then counterintuitively, the image become draggable again. Weird, I know! Using FF 16.0.1

So, does anyone know why adding -moz-user-select: none, would somehow trump and disable draggable=false? Of course, webkit works as expected. Nothing is out there on the Interwebs about this...It would be great if we could shine some light on this together.

Edit: This is about keeping UI elements from being inadvertently dragged and improving usability - not some lame attempt at a copy protection scheme.

Css Solutions


Solution 1 - Css

Set the following CSS properties to the image:

.selector {
    user-drag: none;
    -webkit-user-drag: none;
    user-select: none;
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
}

Solution 2 - Css

I've been forgetting to share my solution, I couldn't find a way to do this without using JS. There are some corner cases where @Jeffery A Wooden's suggested CSS just wont cover.

This is what I apply to all of my UI containers, no need to apply to each element since it recuses on all the child elements.

CSS:

.unselectable {
    /* For Opera and <= IE9, we need to add unselectable="on" attribute onto each element */
    /* Check this site for more details: http://help.dottoro.com/lhwdpnva.php */
    -moz-user-select: none; /* These user-select properties are inheritable, used to prevent text selection */
    -webkit-user-select: none;
    -ms-user-select: none; /* From IE10 only */
    user-select: none; /* Not valid CSS yet, as of July 2012 */

    -webkit-user-drag: none; /* Prevents dragging of images/divs etc */
    user-drag: none;
}

JS:

var makeUnselectable = function( $target ) {
    $target
        .addClass( 'unselectable' ) // All these attributes are inheritable
        .attr( 'unselectable', 'on' ) // For IE9 - This property is not inherited, needs to be placed onto everything
        .attr( 'draggable', 'false' ) // For moz and webkit, although Firefox 16 ignores this when -moz-user-select: none; is set, it's like these properties are mutually exclusive, seems to be a bug.
        .on( 'dragstart', function() { return false; } );  // Needed since Firefox 16 seems to ingore the 'draggable' attribute we just applied above when '-moz-user-select: none' is applied to the CSS 

    $target // Apply non-inheritable properties to the child elements
        .find( '*' )
        .attr( 'draggable', 'false' )
        .attr( 'unselectable', 'on' ); 
};

This was way more complicated than it needed to be.

Solution 3 - Css

You can use the pointer-events property in your CSS, and set it equal to 'none'

img {
    pointer-events: none;
}

Edited

this will block (click) event. So better solution would be

<img draggable="false" (dragstart)="false;" class="unselectable">

.unselectable {
  user-drag: none; 
  user-select: none;
  -moz-user-select: none;
  -webkit-user-drag: none;
  -webkit-user-select: none;
  -ms-user-select: none;
}

Solution 4 - Css

Depending on the situation, it is often helpful to make the image a background image of a div with CSS.

<div id='my-image'></div>

Then in CSS:

#my-image {
    background-image: url('/img/foo.png');
    width: ???px;
    height: ???px;
}

See this JSFiddle for a live example with a button and a different sizing option.

Solution 5 - Css

You could probably just resort to

<img src="..." style="pointer-events: none;">

Solution 6 - Css

A generic solution especially for Windows Edge browser (as the -ms-user-select: none; CSS rule doesn't work):

window.ondragstart = function() {return false}

Note: This can save you having to add draggable="false" to every img tag when you still need the click event (i.e. you can't use pointer-events: none), but don't want the drag icon image to appear.

Solution 7 - Css

I created a div element which has the same size as the image and is positioned on top of the image. Then, the mouse events do not go to the image element.

Solution 8 - Css

You could set the image as a background image. Since it resides in a div, and the div is undraggable, the image will be undraggable:

<div style="background-image: url("image.jpg");">
</div>

Solution 9 - Css

Here's a four-part solution that should work in nearly every modern browser:

<img src="foobar.jpg" draggable="false" ondragstart="return false;">

img
{
    user-drag: none;
    -webkit-user-drag: none;
    
    user-select: none;
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
}

You can remove the bottom four lines of CSS if you want to allow selecting/highlighting.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiontmkly3View Question on Stackoverflow
Solution 1 - CssJeff WoodenView Answer on Stackoverflow
Solution 2 - Csstmkly3View Answer on Stackoverflow
Solution 3 - CssLinh DamView Answer on Stackoverflow
Solution 4 - CssNick MerrillView Answer on Stackoverflow
Solution 5 - CssThomas BachemView Answer on Stackoverflow
Solution 6 - CssPhilip MurphyView Answer on Stackoverflow
Solution 7 - CssUserView Answer on Stackoverflow
Solution 8 - Cssjoshua pogi 28View Answer on Stackoverflow
Solution 9 - CssPikamander2View Answer on Stackoverflow