How can I render content invisibly with CSS? - javascript

I'm trying to implement a simple tabs component in a single-page app. The selected tab should (obviously) display its contents while unselected tabs keep their content available but hidden. How should I hide the content on the unselected tabs?
Each of the canonical techniques for hiding content has issues:
technique
drawback
opacity: 0
User can still potentially interact with invisible content. Breaks if a sub-element of the tab element sets the opacity property.
color: transparent, background: transparent
Same issues as above.
display: none
Component on unselected tabs is loaded in a div with no dimensions, which in my experience causes rendering issues when that content is later displayed. (Several React libraries I'm using do not properly calculate inner dimensions of columns or whatnot when they're initially rendered in a display: none div and later displayed.)
visibility: hidden
Still takes up room on the page. Breaks if some sub-element of the tab element sets the visibility property.
To sum up: I want to know how to render content as if it's actually loading on the page (i.e., with the proper dimensions), but completely invisibly, with no space reserved for it on the page and with no possibility of user interaction. Ideally, the solution should be agnostic to whatever CSS properties are set on the arbitrary component within the tab itself; i.e., the CSS inside the tab content should not be able to break the display of the tabs themselves. Is there some recommended combination of CSS properties (visibility, opacity, display, position, z-index, etc.) that does what I want here?

Related

Shrink web page to fit content

I am in the process of reworking a simple web site so that it can run on a thumb drive, aka with no server involved.
On a page on the original I had a "select" control that would execute a script that read a file and loaded images and some text.
Since I can't load files from the client's computer, I put all the information on the page, each entry in a separate div, each with a unique id, and am using style.visible = "hidden" and "visible" to hide the ones I don't want to see and show the ones I do.
Problem is, the page stays the same size (length) as if each of the divs was visible, and the space occupied by the divs I have hidden is not released.
How do I get the hidden divs to give up their space?
Here's the original page: https://www.vintagebankantiques.net/people.html
A css rule like
.class-of-divs{
min-width: 100%
}
or possibly
.class-of-divs{
min-width: 100vw
}
should help. Without having a JS fiddle or something it's hard to say more.
What these rules do is say that those divs must all be 100% of the width of the page, and shouldn't change size based on the presence of the other divs.
A problem you might get is that the divs will still get shifted in position by their neighbours. To prevent that, you could try setting display: none instead of visible: hidden. The key difference is that a div with a visibility of hidden still affects page layout. A div with a display of none does not affect page layout.

Show/hide div element according to screen size, but allow that to be reversed by clicking a button

I have a site where I want to be able to show or hide a div based on both user input (clicking/tapping a button) and screen size:
a) If the screen width is greater than a certain size, show the div but allow the user to hide it.
b) If the screen with is less than a certain size, hide the div but allow the user to reveal it.
What I'm struggling with is getting these two requirements to interact properly.
I'm using Foundation 5 and jQuery, so both parts of this are possible - Foundation's "show-for-foo-up" handles initial visibility, and there are numerous jQuery functions that allow a div to be toggled between visible and hidden. But what I can't seem to do is find a way to allow a user click to reveal a div that has initially been hidden by Foundation's media query, or a way to do a pure jQuery toggle (ignoring Foundation) that sets the initial visibility according to screen size.
What makes this more complex is that the div contains a form. So I can't simply repeat it in two different divs and toggle between them, as doing that would either mean duplicate element ids or two different forms, both of which aren't possible in this scenario.
Does anyone have any suggestions? I'm open to either a jQuery solution, a Foundation solution or a pure javascript solution, just so long as it works!
Yes, CBroe's comment put me on the right track and my assumption thereafter was correct. All it needs is to use jQuery to alter the class of the div to add or remove the class which uses a media query. Dunno why I didn't think of this before, really.

Prevent Cursor from changing on overlap

I am writing the CSS and HTML for a site currently under construction, something I am not too familiar with having to code.
I have, per request, created a navigation menu that sits on the left side of the screen and expands to cover the page content partially when clicked, allowing the user to show and hide the nav when not needed.
The content that the nav overlaps when it is opened is a bunch of tables, with clickable cells and resizable columns (i.e. they change the cursor to a pointer to allow the user to know they can do something with the cells/table columns)
But when the nav expands over the page content, I am still picking up the cursor changes behind it, making it seem clickable in wrong locations.
Can anyone point me in the right direction on how to prevent elements on the page from picking up cursor changes on elements behind it?
I can probably dynamically change the CSS using javascript when the navBar is opened and closed (remove the cursor on open, add it back when closed) but I am searching for a simpler and more universal fix that can be utilized in the future as well.
Sounds like you need to set the z-index property for each of your elements.
If you create elements without assigning a z-index they'll be indexed automatically, any elements you create after you create the nav will have a higher z-index by default.
Make sure all of your elements have a z-index and that the nav has a higher z-index than the elements it will overlap, example:
.nav {
z-index: 100;
}
.el1 {
z-index: 99;
}
.el2 {
z-index: 98;
}
Etc, think of it as layering your elements on top of one another, the if an element has a higher z-index than another it will be on top of it.
You can force cursors to be a certain way using the cursors CSS property (MDN). See below, where I force all elements that aren't links to have a regular cursor:
*:not(a) {
cursor: default
}
Also, see #Nunchy's answer to correctly configure z-indexs so this type of thing won't happen

Lazy load for table

Setup:
So, I have a narrow but long table (width:200px, height:2000px ish). This table is wrapped inside another div with fix height (300px) and overflow-y:scroll, giving a fixed height visible area. In the table, there is a lot of cells that are stacked vertically (see image and markup is simple regular table wrapped in a div).
Problem:
Each cell contains images, so if there are lots of cells that the page has to fetch including the images and data before loading the site then it will slow down the site significantly.
Solution Approach:
I am thinking of two approaches.
Apply lazy-load to images only. In this case (for example, from the image above). all three sections (section 1, 2 and 3) will be fully loaded except images that are not visible yet. Although it will minimize the delay if it has to fetch lots of data (for example 100+ cells), then I am not sure if it is the best approach.
Another approach is little bit more complicated but will minimize the delay as much as possible and is really ideal. So, when the page is first loaded, only the section-1 will be visible but section-2 will be also loaded (either with images or lazy-loaded images. Howeversection-3will not be loaded at this point.
When the user scrolls to thesection-2then thesection-3will be automatically loaded but not visible until user scrolls down. Ifsection-3is in the viewpoint, thensection-4` will be loaded but not visible. You get the point.
Any thoughts on it and how-to?
Thanks.
Do both. Make sure your images are always being lazy loaded, and only get the data for the next section when the user is scrolling and gets close to (or at) the bottom.
I use a lazyload image system where I specify my images like this:
<div class="lazyimg" data-src="path/to/image">
</div>
I give .lazyimg a width and height and then, when it scrolls into view, I load data-src and set background-image on the .lazyimg element.
This only works if you can specify a size independent of the actual image size, background-size: cover|contain are your friends here.
EDIT
Alternatively I guess you could load the image and then pop it in the DOM as an img tag, but changing the dimensions of the element could affect any sibling layout which could appear somewhat jarring, even if smoothly animated.
How to do it: onscroll callback.

Horizontally distributed, dynamic content

I have a fluid-width div filled with thumbnails from a JSON query, and I am attempting to evenly distribute these thumbnails across the width of the div. These thumbnails must be allowed to wrap and reflow if the width of the enclosing div changes, and may vary in x- and y- dimensions, as well as in the number of thumbnails loaded.
I have found using text-align: justify; and display: inline-block does exactly what I want with static HTML elements, like so:
http://jsfiddle.net/skywalkar/gUcvq/
When I do the same thing with content fetched via JavaScript, however, it reverts to plain left-justified alignment (if it even renders at all-- Chrome and Firefox render it as left-justified, but IE seems to give up displaying the thumbnails altogether!):
http://jsfiddle.net/skywalkar/KdLyx/
My question, then, is this:
How can I force the JavaScript-loaded thumbnails to be horizontally justified like the HTML version?
You have 2 problems here. First, your span is outside of the div (honestly, you don't even need the span, just use the :after pseudo element).
Second, justification relies on whitespace. You're inserting your images without including a space/newline/etc. That's why they won't justify.
http://jsfiddle.net/KdLyx/7/

Categories