How to hide an element when display: none doesn't work - javascript

Here's the deal. I have troubles while trying to hide a paragraph element with a class"text".Link to the pen I've tried display:none but it didn't work for me either.
<style>
.img {
position: absolute;
left: 40%;
transform: translateX(-50%);
}
.p-wrap {
color: #fff;
position: relative;
display: none;
}
.text {
display:none;
color: #000;
position: absolute;
left: -130px;
}
</style>
<div class="img">
<div class="p-wrap">
<p class="text"> Oh hey Mark</p>
</div>
<img
src="https://source">
</div>

besides from display:none,other alternatives are
visibility: hidden;
opacity:0
But be carefull , with this element is still present in DOM(space is still allocated.)

You missed a closing quote mark there on a div with class p-wrap, so your DOM is not correctly generated.
<div class="img">
<div class="p-wrap">
<p class="text"> Oh hey Mark</p>
</div>
<img
src="https://nypdecider.files.wordpress.com/2018/09/the-room-youtube.jpg?quality=80&strip=all&w=646&h=431&crop=1">
</div>
This will fix it.

Use visibility:hidden
.img {
position: absolute;
left: 40%;
transform: translateX(-50%);
}
.p-wrap {
color: #fff;
position: relative;
display: none;
}
.text {
visibility:hidden;
color: #000;
position: absolute;
left: -130px;
}
<div class="img">
<div class="p-wrap">
<p class="text"> Oh hey Mark</p>
</div>
<img
src="https://source">
</div>

There are multiple ways of hiding an element in CSS. You can hide it by setting opacity to 0, visibility to hidden, display to none or by setting extreme values for absolute positioning.
Have you ever wondered why we have so many techniques of hiding an element when they all seem to do the same thing? All of these methods actually differ slightly from each other and this difference dictates which one of them is to be used in a specific situation. This tutorial will cover the minor differences that you need to keep in mind when hiding an element using any of the methods above.
Opacity
The property opacity is meant to set an element’s transparency. It was not designed to alter the bounding box of the element in any way. This means that setting the opacity to zero only hides the element visually. The element still occupies its position and affects the layout of the web page. It will also respond to user interaction as well.
.hide {
opacity: 0;
}
Visibility
This property is also able to animate as long as the initial and final states have different values. This ensures that the transition between the states of visibility can be smooth instead of being abrupt.
.hide {
visibility: hidden;
}
Display
All the descendants of our element will be hidden as well. This property cannot be animated so the transition between various states is always going to be abrupt.
Please note, the element is still accessible through the DOM. You will be able to manipulate it just like with any other element.
.hide {
display: none;
}
Position
Suppose you have an element that you would like to interact with but you do not want it to affect the layout of your web page. No property up to this point can handle this situation properly. One thing that you can do in this situation is to move the element out of the viewport. This way it won’t affect the layout and will still be actionable. Here is the CSS to do that:
.hide {
position: absolute;
top: -9999px;
left: -9999px;
}
Clip-path
One more way of hiding elements is by clipping them. Previously, this could be done with the clip property but that has been deprecated in favor of a better property called clip-path. Nitish Kumar recently introduced the clip-path property here at SitePoint, so feel free to check that one out for more advanced usage of the property!
Keep in mind that the clip-path property as used below is not fully supported in IE or Edge yet. If using external SVG files for your clip-path, support is even more limited (that does not apply below). The clip-path property when used to hide an element looks like so:
.hide {
clip-path: polygon(0px 0px,0px 0px,0px 0px,0px 0px);
}

Related

blur everything except a particular div

I want to blur the entire background once a div appeared. I have hidden the div and it will appear in button click. on that div appearance, the entire background should be blurred. how can I do that?
It would have been better if you have provided us with the code you are working with. Nonetheless, check the following out. It might help you.
You can do this using backdrop-filter: blur() instead of filter: blur() to make sure the elements behind the .backdrop are blurred, instead of the element itself.
I hope the code is self-explanatory (the complete code on CodePen). But if you are wondering, it's just the .backdrop positioned over all the elements using position: fixed; and z-index:9998;. And then the .except is placed over the .backdrop using z-index: 9999; which is one level higher than the .backdrop but only using position: relative; so it's at the same place as it was before. You can position it wherever you want it to be.
This way you can blur everything including the backgrounds except for the desired element and you don't need to reposition the .except element somewhere else this way if you don't want to.
Let me know if you need more clarification.
.except {
background: white;
position: relative;
z-index: 9999;
}
.backdrop {
position: fixed;
z-index: 9998;
top: 0; bottom: 0; left: 0; right: 0;
background: #33333377;
backdrop-filter: blur(4px);
}
<div class="wrap">
<div class="content">Some text</div>
<div class="content except">Some text</div>
<div class="content">Some text</div>
<div class="content">Some text</div>
</div>
<div class="backdrop"></div>
Demo with the complete code on CodePen
you could do the following
in your css
.blur {
filter: blur(5px);
}
javascript file
document.querySelector("*").classList.add("blur");
document.querySelector("div_id").classList.remove("blur");

Why does will-change:opacity treat fixed elements differently than will-change:transform in chrome?

I am trying to optimize the scrolling of my web app. I have data tables with tons of data, and scrolling gets pretty bad. I added will-change: transform to the data table but it broke my table headers that are position: fixed (I make them fixed to allow them to scroll with the viewport). The elements don't move with the viewport at all, they just stay stuck in the flow of the document.
But by chance I discovered that if I use will-change:opacity instead, my fixed headers are fine. Can someone explain this behavior? I haven't been able to find any documentation that says they should act differently.
Here is a code pen with an example of what I am talking about. Toggle between the values, and scroll in blue div.
https://codepen.io/bkfarns/pen/aLYgrN
Here is the basic code from the pen too:
html:
<div class="container">
<div class="fixed">should be position: fixed</div>
<div class="too-tall">div that is too tall</div>
</div>
css:
.container {
margin-left: 100px;
background-color: blue;
width:400px;
height:300px;
overflow: auto;
will-change: transform;//changing this to opacity fixes the issue
}
.fixed {
background-color: grey;
position: fixed;
margin-left: 150px;
margin-top: 100px;
}
.too-tall {
background-color: red;
width: 90px;
height: 600px;
}
The whole point of will-change is to make all possible changes that browser would have to apply when the specified property will change in advance, reducing the time needed for the change itself. Effectively it means that by specifying will-change:transform you make the element transformed (though visually it stays in the same position), and descendants of the transformed elements can't be fixed per the CSS Transforms spec. Opacity doesn't have such effect, so will-change:opacity doesn't break fixed positioning.
Also, will-change per se doesn't have any "optimization magic", it only optimizes the changes of the specified properties. Some properties force the elements to the composite layers that theoretically can be processed by the GPU more efficiently, but if there is too many such elements it may have the opposite effect. For optimizing scrolling, probably other strategies would be more efficient.

Capturing an event through a DOM layer that contains other event listeners

tldr; I want to have a button's event captured (click) even though it's under a DOM layer.
Here's my problem, I have a DOM layer that's relatively positioned and has a z-index set higher than 1, let's just say 2. That DOM layer is above the button (Button A) I'd like to have triggered when clicked. The reason that DOM layer is above the button (Button A) in question, is that the button (ShoreMore) across from it has another event that when clicked, opens a drawer of other little links.
Here's what I've tried:
I tried adding pointer-events: none; to the DOM layer above my button. problem is that while it now allows the button to be pressed, the DOM layer with the button that opens the drawer of other link no longer works. Suggested by this SO question.
I also came across this little trick found on this website. It essentially, hides the mask and rechecks the user's click coordinates and fires the event that is found within the coordinate. However, I found myself unsatisfied with the results, as I'm often given DOM that's unhelpful too specific or too broad based on the user's click. (e.g. getting the icon, text next to the icon, etc. of the Button).
For illustration purposes, here's what I have:
Here's my code:
HTML
<div id="drawer" class="drawer">
<div id="shield" class="shield"></div>
<div id="expander" class="expander">
<div class="inner">
<ul>
<li>links</li>
<li>links</li>
<li>links</li>
<li>links</li>
<li>links</li>
</ul>
<div id="tab" class="tab" >
<i class="icon"></i> Show More
</div>
</div>
</div>
</div>
<span id="btnA" class="btn">
<i class="icon"></i>
<span>Button A</span>
</span>
CSS
.drawer {
position: relative;
height: 0;
z-index: 2;
margin-bottom: .5em;
}
.expander {
position: relative;
height: 28px;
transition: height .2s ease;
overflow: hidden;
}
.inner {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
margin-bottom: 28px;
}
I didn't include the javascript, but "Button A" and "Show More" have a click listener. They both work, but Button A is confirmed to work if pointer-events: none; is added to the CSS of the class "expander."
EDIT: spelling
One possible solution is to use more absolute positioning.
The problem you're running into is that HTML elements, no matter their shape, end up as rectangles when rendered. Your blue outlined layer has a complex shape that's not strictly rectangular, but HTML doesn't care - it expands the layer's shape into a big rectangle to cover the parent element and all of its children elements, as you've correctly drawn in your diagram.
Absolute positioning helps prevent that from happening. Instead of leaving space for an element in the document flow, absolute positioning sort of pops the element out and positions it relative to its parent. The result is an element that doesn't expand the borders of its parent element, because it essentially takes up zero space in the normal document flow.
Consider the following example:
$(function(){
function slideDown(){
this.innerHTML = "Close";
$("#tray").animate({top: "50px"});
$("#higher-button").off("click").on("click", slideUp);
}
function slideUp(){
this.innerHTML = "Show More";
$("#tray").animate({top: "0px"});
$("#higher-button").off("click").on("click", slideDown);
}
$("#higher-button").on("click", slideDown);
$("#lower-button").on("click", function(){
alert("Lower button clicked.");
});
});
* {
margin: 0;
padding: 0;
text-align: center;
line-height: 50px;
}
#box {
position: absolute;
top: 20px;
left: 20px;
}
#lower-button {
width: 200px;
height: 50px;
background-color: #cccccc;
position: absolute;
top: 50px;
}
#higher-button {
width: 200px;
height: 50px;
background-color: #888888;
position: absolute;
top: 50px;
left: 200px;
}
#tray {
width: 400px;
height: 50px;
background-color: #aaaaaa;
position: absolute;
}
#mask {
position: absolute;
width: 400px;
height: 50px;
background-color: #dddddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box">
<div id="lower-button">Button A</div>
<div id="tray">
<div id="higher-button">Show More</div>
</div>
<div id="mask">Mask</div>
</div>
Absolute positioning lets you easily layer and position elements in a way that avoids them taking up excess space.
The caveat to all this is that absolute positioning can be pretty messy. Since it removes elements from the normal document flow, they don't take up any space, and it can wreak havok with your layouts. So use absolute positioning sparingly, for cases like this where you're building a UI element that you probably don't need taking up space in the layout anyway.
As always there are dozens of ways to solve this problem and this is only one possibility, but I hope it helps you figure out your own solution. Good luck!
Edit: Note you don't necessarily need to make all of the UI elements absolutely positioned, only the ones you need in order to manage the document flow. For example, the parent UI element could still be relatively positioned, and you just "pop out" the individual UI components. You still need to manually manage the size of the parent UI container, because absolutely positioned elements take up zero space in the flow. jsfiddle.net/v2646v41
One easy solution would be to change the z-index of Button A. When the drawer is closed, set it higher than the drawer's div, and when Show More is clicked, set the z-index underneath, then back above after the drawer has slid back under the mask.

Position fixed within container element instead of the browser / viewport

I need to position a header to be fixed within the containing parent so that it follows when scrolling. The problem is that
position:fixed
fixes the position to the browser, not the parent. What this is resulting in is that when I have a container that has a horizontal scroll for overflow in the width (the content is wider than the container), my fixed header does not have the overflow-scroll as the content of the table does.
See this fiddle demo
So the goal here is to fix the position of the header, but fixed relative to it's parent container. In this fiddle, you can see that I've commented out a block of css:
.container{
/*-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);*/
-webkit-transform: none;
-moz-transform: none;
-ms-transform: none;
transform: none;
}
If you replace the current css block (with transform set to none) with the one with translateZ, the header will get positioned within it's parent container, but is no longer fixed.
Anyone know how to solve this? Preferred solution would be CSS/HTML only and avoid JS but if nothing else, then JS is of course what I need to go with!
CSS can't do this by itself.
Position: fixed works in relation to the viewport, not it's containing element.
I've seen an attempt to solve this problem using the CSS3 transform property, but (as you noted in your comment to my first answer) it doesn't seem to work.
I understand you can't use any client-side library but that's the only solution available to my knowledge. For you and others who may one day need this, here's a solution that works. It employs a bit of jQuery:
Positioning an element inside another element with the positioned element fixed along the x and y axes (i.e. position fixed horizontally and vertically).
http://jsfiddle.net/8086p69z/8/
HTML
<div class="moving-article">
<div class="container">
<header class="fixed-header">FIXED HEADER</header>
<ul>
<li>SCROLL</li>
<li>SCROLL</li>
<li>SCROLL</li>
</ul>
</div>
</div>
CSS (relevant section)
.moving-article {
height: 150px;
width: 75%;
overflow-x: scroll;
}
.fixed-header {
background: rgba(0,0,0,0.5);
width: 50%;
text-align: center;
line-height: 40px;
position: absolute;
top: 0;
left: 0;
}
.container{
width: 1000px;
}
jQuery
var leftOffset = parseInt($(".fixed-header").css('left'));
$(window).scroll(function(){
$('.fixed-header').css({
'left': $(this).scrollLeft() + leftOffset
});
});
set the header's position to 'absolute', and it's parent container (which you want it to be relative to) to 'relative', and set it to stick to the top of the parent with 'top: 0'
CSS:
.container {
position: relative;
}
.child {
position: absolute;
top: 0;
}
To keep an element fixed within a parent cannot be done with position: fixed because position: fixed takes the element out of the flow and therefore it has no parent. It positions itself relative to the viewport.
To accomplish your goal, while keeping things simple and efficient, you may want to consider Tether, "a client-side library to make absolutely positioned elements attach to elements in the page efficiently".
Hope this helps. Good luck.

Centering unknown width object in an unknown width container

I have a styling issue where I'm trying to center a wide image relative to it's container. The problem is that the image's width is unknown so I can't do the left:50%, margin-left:-###px; trick because I don't know what the negative margin value will be.
I also can't use text-align:center; because the the image is wider than it's container.
To make matters more complicated, the container's width is also unknown.
I'd quite like to avoid using JavaScript for this but it feels like a big ask with just CSS.
Anyone know of any magical solution here?
UPDATE:
Required support: IE8+, Chrome, Safari, Firefox, Android.
I have tried a couple of the examples provided by you lovely people which have not worked (they would work in most situations, but not mine).
#Vince - I tried your display block trick which works great when the window is wider than the image but when the window is not wider than the image, it effectively becomes 'left-aligned'.
See fiddle example. I have added another container to simulate a narrow mobile device window. Obviously this won't be a hard-coded width as in the fiddle. Also, the img width will not be hard-coded as in the example but I'm trying to simulate the situation that's presented to me.
http://jsfiddle.net/7n1bhzps/1/
Excuse the hideous colours.
UPDATE 2:
Accepted dfsq's answer. Contrary to above, it does not need to support IE8 because the problem is at mobile resolutions. IE8 is not a mobile browser so the need to support this is not necessary.
Thanks all.
Set the container's min-width to any value you feel necessary. Set the image to display as block and use the margin: 0 auto; trick to center it
HTML:
<div id="contain">
<img src="http://i.imgur.com/xs8vh.jpg"/>
</div>
CSS:
#contain {
min-width: 50px;
}
#contain img {
display: block;
margin: 0 auto;
}
JSFiddle: http://jsfiddle.net/j21a8ubo/
You can make use of CSS transofrm: translateX(-50%) to shift the image of unknown width. This technic allows to center image of any width relative to container.
.wrap {
margin: 0 0 10px 160px;
width: 300px;
height: 75px;
border: 3px red solid;
position: relative;
overflow: hidden;
}
.wrap:hover {
overflow: inherit;
}
.wrap img {
position: absolute;
left: 50%;
-ms-transform: translateX(-50%);
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
}
<div class="wrap">
<img src="http://lorempixel.com/600/75/food/3" alt="">
</div>
<div class="wrap">
<img src="http://lorempixel.com/100/75/food/4" alt="">
</div>
Check for support http://caniuse.com/#feat=transforms2d
If you set X's CSS to margin:0px auto; it should center it within the parent container.
Sometimes centering doesn't work, but this can also be a browser-related issue.
If you can adjust the HTML, you could put the element to be centered in a cell in a <table> element, with a cell on either side of it. This is how it was done in IE8 and earlier, though it's not recommended now.
If unknown width of object and its container then use
.center-block{
display: table;
margin:0 auto;
float:none;
}

Categories