Allow users to click on elements under a div's blank space? - javascript

I had an element which was the top level dom elemnt. I decided to build a user interface over the top, allowing for items to be placed in interface-overlay. It seems I can't click anything inside my interface-overlay, but I can click underlying elements?
Sure, I want to click underlying elements, but I also want to be able to click the overlay, and also click the underlying elements where the overlay doesn't have any dom elements covering it.
I used this, but it seems to block for all space:
pointer-events: none;
If I remove the pointer-event attribute, it flips the issue. I can click the overlay but not the underlying elements.
Code pen showing the issue: https://codepen.io/samhabbo/pen/ExymBBK

One option is to apply pointer-events: none to the parent container but then reset it back to auto on child elements:
.interface-overlay {
/* ... */
pointer-events: none;
}
.interface-overlay > * {
pointer-events: auto;
}
html, body {
margin: 0;
}
.tile {
opacity:0.8;
background-color:#ccc;
position:fixed;
width:100%;
height:100%;
top:0px;
left:0px;
padding: 50px;
}
.interface-overlay {
position: absolute;
z-index: 5;
width: 100%;
height: 100%;
padding-left: 20px;
color: #FFFF;
pointer-events: none;
}
.interface-overlay > * {
pointer-events: auto;
}
button.button {
background-color: red;
}
<div class="interface-overlay">
<button class="button">Overlay button</button>
</div>
<div class="tile">
Some tile content.
<button class="button" onclick="alert('test');">Underlying button</button>
</div>

Related

Make fixed page elements "honor" the body right padding?

My fixed button triggers a menu. While menu is opened, the body has overflow-y: hidden and a padding-right: 17px (actually this value is computed, omitted for brevity). The button (position: fixed) is shifted.
The HTML (the <p> is only needed to show the scrollbar):
<body>
<button class="btn">
Menu
</button>
<p style="height: 5000px;"></p>
</body>
To the CSS... note that .menu-opened is added when you click the button, via JavaScript:
body {
background-color: blue;
}
body.menu-opened {
padding-right: 17px;
overflow-y: hidden;
}
/* Useless styles */
.btn {
background-color: red;
position: fixed;
padding: 1rem;
top: 0;
right: 0;
margin-right: 2rem;
margin-top: 2rem;
}
Example pen here
As soon as the scrollbars are disabled, button is shifted because fixed elements doesn't honor the body padding (which is added to compensate the absence of the scrollbar). Any idea on how to solve this, without touching all fixed elements?
I think this is a common problem, so there should be an easy solution, but I can't get it.
Take a look at scrollbar-gutter: MDN: scrollbar-gutter

CSS add div to dom positioned relative to parent without other content jumping

I'm trying to make a short pop up in my web app for when a user clicks on a code to copy it. The trouble I'm having is trying to figure out to make it not shift everything in the parent div.
The gif below is what currently happens after all my attempts and googling of trying to solve this problem. What I'm trying to get to happen is have that copied message bubble just appear to the top right of the span with the room code.
This fiddle is a stripped down version of the interaction. I've tried all the different display and positionings and I'm not really sure where to go from here. Thanks in advance to everyone.
https://jsfiddle.net/k6ey1duc/36/
.container {
background-color: #008afa;
width: fit-content;
margin: auto;
padding: 20px
}
.text {
display: inline;
}
.pop-up {
display: none;
background-color: #fe0c0d;
}
#show-hide {
display: block;
margin: auto;
}
<body>
<script>
$(document).ready(function() {
var x = false;
$('#show-hide').on('click', function() {
if (!x) {
$("#pop-up").css({
"backgroundColor": "#fe0c0d",
"display": "inline"
});
x = true;
} else {
$("#pop-up").hide();
x = false;
}
});
});
</script>
<div class='container'>
<p class='text'>
Hello there! <span>Here is a span.</span>
</p>
<div id='pop-up' class='pop-up'>
Here is a pop-up
</div>
<button id='show-hide'>
Click for pop up
</button>
</div>
</body>
Adding position: absolute; to .pop-up will prevent the container from making any space for the element which is what you are trying to prevent. Additionally, adding position: relative; to .container will give you freedom to position .pop-up anywhere relative to the container.
Another solution is replacing the display: none; display: inline; with visibility: visible; visibility: hidden;. The main difference between these two is that display will remove the entire element from the layout whereas visibility will only hide the element but retain the elements space. This will solve the resizing container problem but will not give you the advantages of stacking and positioning that position: absolute does.
.container {
position: relative;
background-color: #008afa;
width: fit-content;
margin: auto;
padding: 20px
}
.pop-up {
position: absolute;
display: none;
background-color: #fe0c0d;
}
Use position:relative and postion:absolute.
.container {
background-color: #008afa;
width: fit-content;
margin: auto;
padding: 20px;
position: relative;
}
.pop-up {
display: none;
background-color: #fe0c0d;
position: absolute;
left:100%;
width:inherit;
}

jQuery hidden element stays hidden when showing with CSS

I have an element which has display:none attribute.
Now if a user hovers the parent, it will be shown:
.item:hover .description {
display: block;
z-index: 1;
}
Now, when I execute
$(".description").hide()
to hide the element again (the user can click an X in the element to close it), the element will not show again if the user is hover the parent again. It stays hidden.
How do I not mess up with the css show and hide functions?
The way you have given your code is you are mixing up CSS and JavaScript. The jQuery uses inline-styles to accomplish the .hide() or show. And inline-styles are more specific than the CSS. Either use classes and toggle them or just use JavaScript.
I would do this way:
.item:hover .description {
display: block;
z-index: 1;
}
.item .description {
display: none;
}
The above is a pure CSS method. But using JavaScript, I would consider using toggleClass() instead of .hide() or .show().
.item:hover .description {
display: block;
z-index: 1;
}
.item .description.hidden {
display: none;
}
And in the JS:
$(".description").addClass("hidden");
And when you want it to be shown, you can always use:
$(".description").removeClass("hidden");
And for toggling things, you can use:
$(".description").toggleClass("hidden");
hide will add an inline style to hide the element, which will override the CSS style in this case.
If you're using JavaScript to hide the element, you'll need to use JavaScript to remove that inline style when no longer relevant. I'd use a mouseleave event handler on .item and a class to hide description:
CSS:
.item:hover .description.hide {
display: none;
}
Hiding description in response to click on X:
$(".item .description").addClass("hide");
Removing that when the user no longer hovers .item:
$(".item").on("mouseleave", function() {
$(this).find(".description.hide").removeClass("hide");
});
Either with direct handlers as above, or with event delegation (I use delegation in the example below).
Live Example:
// Hide when X clicked
$(document.body).on("click", ".item .description .close", function() {
$(this).closest(".description").addClass("hide");
});
// Reset when user no longer hovering
$(document.body).on("mouseleave", ".item", function() {
$(this).find(".description.hide").removeClass("hide");
});
.item .description {
display: none;
}
.item:hover .description {
display: block;
z-index: 1;
}
.item:hover .description.hide {
display: none;
}
/* The following are just for the demo */
.close {
cursor: pointer;
}
.item {
position: relative;
height: 2em;
border: 1px solid black;
}
.item .description {
position: absolute;
background-color: #eee;
left: 10em;
top: 2px;
border: 1px solid #ddd;
}
<div class="item">
I'm item 1
<div class="description">
I'm description 1
<span class="close">[x]</span>
</div>
</div>
<div class="item">
I'm item 2
<div class="description">
I'm description 2
<span class="close">[x]</span>
</div>
</div>
<div class="item">
I'm item 3
<div class="description">
I'm description 3
<span class="close">[x]</span>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
It's because during hiding this element by JS, you set visibility: hidden to it. After next focus on parent, you won't set visibility: visible which is required.
You can for example execute
$(".description").show()
after next focus on parent element

Partially exposed div to slide up when image is clicked

this might be a weird one but what I am trying to do is make a div slide up from the bottom of the screen when someone clicks an image. To paint this clearer, imagine the Windows desktop, and if you click the start menu image/icon, instead of the start menu popping up from the button, the entire start menu bar would slide up exposing the entire div.
What I'm doing now (forgive me as I have just learned JS and jQuery from codecademy) is using the slideUp function. However, this is causing the div to slide down out of sight instead of up, exposing the entire div. The goal is that when you click the button the div slides up, and if you click the button again (or anywhere outside the div) it'll slide back down leaving the top 60px exposed like before.
Here's my JS/jQuery code:
$('#start').click(function() {
$('#nav').slideUp('slow');
});
My HTML
<div id="nav" class="nav">
<img id="start" src="img/btn_start.png">
</div>
My CSS
* {
padding: 0px;
margin: 0px;
}
body {
width: 100%;
font-family: Helvetica;
}
.nav {
width: 100%;
min-width: 100%;
height: 500px;
background: #000;
color: #fff;
position: absolute;
bottom: -440px;
text-align: center;
padding: 5px;
box-sizing: border-box;
overflow: auto;
}
.nav ul li {
display: inline;
}
.nav li {
padding: 20px;
margin-top: 80px;
position: relative;
top: 50%;
transform: translateY(-50%);
}
#start {
float: left;
}
Thanks, and I hope this isn't too ridiculous.
Instead of slideUp you should use
$('#start').click(function() {
$('#nav').animate({bottom: "0px"}, 1200);
});
...which will smoothly animate from the current location until the bottom is at 0px (i.e. aligned with the bottom of the containing element).
For even smoother results, checkout velocity.js (http://julian.com/research/velocity/), which does even smoother animation by synchronising with browser frame updates.
JsFiddle here: http://jsfiddle.net/11r46jnm/
You can also do this with CSS transitions instead. For stuff like this I like to hook my CSS into data attributes on the HTML:
<div id="nav" class="nav" data-nav-state="collapsed">
<img id="start" src="img/btn_start.png">
</div>
...use javascript to change the attributes...
$('#start').click(function() {
//toggle the nav element between two states
var currentState = $('#nav').attr("data-nav-state");
var newState = "collapsed";
if ( currentState === "collapsed" ) {
newState = "expanded";
}
$('#nav').attr("data-nav-state", newState);
});
Finally we use CSS to set the positions of the two states, and to ensure that transition is smooth. CSS transitions have much better performance than jQuery, so I recommend using them if you can:
#nav[data-nav-state=collapsed] {
bottom: -440px;
}
#nav[data-nav-state=expanded] {
bottom: 0px;
}
#nav {
transition: bottom 1.2s ease;
}
See this jsFiddle for a demo: http://jsfiddle.net/Lv2saepy/1/

CSS - displaying a dynamic height floated DIV - missing background image

My Goal:
Here is what I'm trying to accomplish. We have an list of categories that appear on a page. The number of categories is unknown. The description can be pretty much any size... yet we want a uniform look. So, we are using the dotdotdot plugin to put ellipses on the paragraphs. When you hover over the item, it should expand the description and show the full text.
I want that hover to float or overlay whatever is below it. Due to some of my layout items (see my NOTE below) my sccontainer element doesn't have a set height. It's dynamic based on the content... with a max-height set.
When I change that height to AUTO in the hover event (which causes the text to flow down and displays all the content), I lose the background on the sccontainer element.
Some pertinent CSS:
.sccontainer { width: 280px; zoom: 1; float: left; margin: 5px 10px; padding: 0; border: 1px solid #8697a1; -moz-border-radius: 5px; border-radius: 5px; -moz-box-shadow: 0 0 6px #777; -webkit-box-shadow: 0 0 6px #777; box-shadow: 0 0 6px #777; -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=6, Direction=90, Color='#777777')"; filter: progid:DXImageTransform.Microsoft.Shadow(Strength=6, Direction=90, Color='#777777'); position: relative; background: #fff url(http://imagecss.com/images/background.jpg) repeat-x left top; }
.sccontainer .parent { position: absolute; width: 270px; }
.sccontainer .image { margin: 5px; float: left; }
.sccontainer .image img { width: 48px; }
.sccontainer .icon { margin: 0; }
.sccontainer p { margin: 8px; padding: 0; max-height: 145px; }
.sccontainer h1 { line-height: 24px; display: inline-block; vertical-align: middle; width: 200px; height: 48px; padding: 0; margin: 5px 0 0 0; overflow: hidden; }
.sccontainer h1 a { padding: 0; font-size: 24px; color: #fff; font-weight: normal; }
.sccontainer .content { position: relative; height: 210px; padding: 0 5px; font-size: 15px; line-height: 22px; width: 270px; }
.sccontainer a:hover { text-decoration: underline; }
.sccontainer.hover { height: 250px; }
.sccontainer.hover .content { height: auto; }
.sccontainer.hover .content p { min-height: 135px; max-height: none; }
jsFiddle:
Here is a jsFiddle version of what I have right now. You can see this in action, if you hover over the text in the blue box. It's a bit large, so I used jsFiddle instead of putting all the bits here code tags...
http://jsfiddle.net/ztMM5/1/
And here is a mockup of what I'd like to see. Method 5a expands slightly to show the full content.... yets overlaps the red line. None of the other items move around or are affected.
NOTE: Sorry for the size of things. I've trimmed it down about as much as I can. Also, I am modifying an existing intranet website... it's 3rd party, so I have limited control of the source code - hence the table usage. :(
What I've Tried/Researched:
I believe the issue stems from the fact that my sccontainer item is floating, and doesn't have a height specified. That's why the image disappears.
I had a version that kept the background... but the sccontainer box didn't resize like we need... the text just overflowed it... rather ugly.
I don't know enough CSS to make this all work right. I'm not adverse to using jQuery to do more if needed.
I did work on a version that handled most of the hover using the :hover stuff... but it didn't work quite as well as the jQuery approach.
This answer may not solve your specific problem but it may help others with a similar scenario (working with tables makes difficult to render a clean layout in most cases.)
I ran into this issue before and this is how I solved it. It basically relies in an html nested div structure to achieve the expandability of the content without affecting the floating layout of the near elements :
<div id="wrapper" class="cf"><!--wrapper with border and CLEARED-->
<div class="sccontainer"><!--position relative-->
<div class="inner"><!--position absolute-->
<div class="content"><!--position relative-->
<!-- my content here -->
</div>
</div>
</div>
<!-- more containers etc-->
</div><!--END wrapper-->
First, we are going to apply the infamous clear-fix hack to the #wrapper container (use your preferred method):
.cf:after {
visibility:hidden;
display:block;
content:"";
clear:both;
height:0
}
* html .cf {
zoom:1
}
/* IE6 */
*:first-child+html .cf {
zoom:1
}
Then the style for the .sccontainer container :
.sccontainer {
width: 280px; /* or whatever - could be % for responsiveness */
padding-bottom:200px; /* any value to give height without using height ;) */
position: relative;
float: left;
margin: 5px 10px; /* or whatever */
overflow: hidden; /* this is important to keep all same height and big content out of sight */
z-index: 1; /* this is important too, see later */
background: white url("imagebackground.jpg") 0 0 repeat-x; /* need to explain? */
}
Then the .inner container, which actually will help to keep the layout in order if we hover the elements
.inner {
position: absolute; /* please don't move */
width: 100%; /* to fill the whole parent container */
height: 100%; /* same */
}
And the content :
.content {
position: relative;
background: white url("imagebackground.jpg") 0 0 repeat-x; /* not redundant though */
width: 100%; /* helps to fill the gaps with small content */
height: 100%; /* same, specially if using image backgrounds */
/* other styles, etc */
}
NOTE: we should apply same border-radius properties to the three containers and box-shadow to .sccontainer and .content for consistency
Now, what happens when we hover ?
.sccontainer:hover {
overflow: visible; /* show the full content */
z-index: 999; /* place me on top of the others if needed (which lower z-index, remember?) */
}
.sccontainer:hover .content {
height: auto; /* as it really is, including background image */
}
NOTES : this effect will happen regardless if the content's height is smaller than the parent container's height. You may not like the effect mostly if you are using borders and shadows (could be shown as smaller box inside the parent container) so we could add an extra class to .sccontainer like
<div class="sccontainer withhover">
and apply the hover effects only if that class exist like
.sccontainer.withhover:hover {
overflow: visible;
z-index: 999;
}
... and use a bit of jQuery to remove that class for shorter content, so it won't be affected :
jQuery(document).ready(function ($) {
$(".sccontainer").hover(function () {
var $contentHeight = $(this).find(".content").height();
if ($(this).innerHeight() > $contentHeight) {
$(this).removeClass("withhover");
}
});
});
See JSFIDDLE

Categories

Resources