8
   jQuery(".my_container").hover(function(){
    //do code
   }, function(){
    //do code
   });

.my_container { width: 100px; height: 100px; margin: 50px; }

The code above doesn't react to mouse over of margin (margin isn't a part of element?) - how can I change that?

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
Atadj
  • 7,050
  • 19
  • 69
  • 94
  • 1
    The margin is'nt part of the element, it's the space around the element that other elements in the natural flow should not occupy, i.e the space between elements. You could use padding instead, but that would only make the element larger, which is probably what you're after anyway, and then just adapt the content to the size of the element. Triggering event handlers on the space between elements would obviously be a really bad idea, and that's why it's not done. – adeneo Jul 02 '12 at 17:46
  • @adeneo I can't go with padding solution because I use padding for styling already and it expands background color area etc. – Atadj Jul 02 '12 at 17:55
  • Then you'll probably have to go with one element inside the other, keep your layout on the inner element and attach the handler to the outer. – adeneo Jul 02 '12 at 19:21
  • @adeneo - yeah, done and works :) – Atadj Jul 02 '12 at 19:51
  • If it's a regular website (and not a game or similar), I'd question the need to ever have the space between elements as a hit target. It's as likely to cause confusion as to increase usability. I'd say if it's necessary, you've an issue with your design to begin with & should look at revising this at a more basic level. – anotherdave Jul 02 '12 at 21:43
  • As @adeneo mentioned, `padding` works - provided it's visible. For example, if the element is an `` tag, then the `overflow` style needs to be set to `visible`. Also, if `padding` isn't an option, perhaps `border` would probably work, it can be made thick and invisible to the user. – Robert Monfera Nov 12 '16 at 22:14

5 Answers5

13

You could use a 50px transparent border instead - the margin isn't really supposed to be mouseable...

Dave Everitt
  • 17,193
  • 6
  • 67
  • 97
  • 6
    Good solution but: (1) transparent border takes background color of element, (2) transparent border "steals" border-radius which is not what I want. – Atadj Jul 02 '12 at 17:52
  • How about adding a 50px margin to the sides of elements surrounding `.my_container`? It won't allow hover there, but your layout could be preserved. BTW why do you need hover outside the main body of the element? – Dave Everitt Jul 02 '12 at 19:01
  • 1
    This won't work if your element needs to have a border defined. I find pseudo element solution by @Dunc below, more versatile. – Jaladh Singhal Oct 22 '20 at 13:28
11

Include a pseudo element, e.g.

.my_container:before {
    content:'';
    position:absolute;
    top:-50px;
    bottom:-50px; 
    left:-50px;
    right:-50px; 
}

This adds an extra 50px to the existing element's clickable area.

If you only want to add this on touch screen devices, you could do this:

.touchevents .my_container:before {
    ...
}

This requires something like Modernizer to insert the appropriate feature-based CSS class.


Update

As per @Jaladh's comments, you may also need to apply position:relative to the container element, since position:absolute above will be relative to the first ancestor with a position attribute:

.my_container {
    position:relative;
}
Dunc
  • 18,404
  • 6
  • 86
  • 103
  • 1
    Also make sure to add `position: relative` to `my-container` class. This will ensure offsets of `before` are relative to `my-container` and not to browser window. (Knowing very little of positioned elements, I made this mistake and it took me an hour to figure this out, so save your time!). – Jaladh Singhal Oct 22 '20 at 13:24
5

Perhaps use a 2nd wrapper element with padding on the outer element and existing background and padding styles on the inner element:

<div class="my_container">
    <div class="my_container_inner">
        <!-- etc. -->
    </div>
</div>
jQuery(".my_container").hover(function(){
  //do code
}, function(){
  //do code
});
.my_container { padding: 50px; }
.my_container_inner { width: 100px; height: 100px; /* etc. */ }
Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199
1

Building upon @Dunc's solution, you can alternatively use pseudo element to mimic your container and let actual container behave like margins. This will look like:

.my_container { 
    width: calc(100px + (2 * 50px));
    height: calc(100px + (2* 50px));

    position: relative;
}

.my_container::before {
    content: '';
    position: absolute;
    top: 50px;
    bottom: 50px; 
    left: 50px;
    right: 50px; 
}

Also make sure to move all other properties (like background color, border, etc.) you had in my_container to my_container::before because before is acting like our container here.

This is essentially helpful if your containers are grid items and you want gaps in-between them to be hoverable, because otherwise using psuedo element to add margins won't work appropriately in that case.

Jaladh Singhal
  • 393
  • 4
  • 10
0

Change the margin to padding and it'll be hoverable.

PriestVallon
  • 1,519
  • 1
  • 22
  • 44