Best way to switch tab ui on webpage, z-index vs display - javascript

The usual way to show\hide block in html is switching it's display property. But in case of performance of rendering, wouldn't it be better to play with z-indexes?
http://jsfiddle.net/WawVH/

Matter of preference really. Display:none removes the element completely, which I think it then is no longer a node in the DOM structure, thus saving memory. Someone correct me if I am wrong.
You could run into a problem with your implementation though if you have overflowing content.
http://jsfiddle.net/yeQfC/
But you could always just turn off overflow with
overflow:hidden;
in your .content CSS definition
http://jsfiddle.net/gF3JC/

Related

Unexplainable CSS Positioning Issue Somehow Related To Transitions

I know that this is not a 'good question' to poseā€”but I'm desperate by now and need to find some inspiration.
I have a questionnaire page/web-app that uses CSS transitions to slide to the next page of questions/options.
It is well-tested and the transitions in question aren't complex.
But the transition to one special page went out of control recently. And although I consider myself well versed in CSS and JavaScript I'm totally lost with this problem.
The construct in question works like this:
I have a 'window' that is positioned absolutely and has its overflow hidden.
Inside that is a page container positioned relative to no left or top values or transforms given.
The pages inside this container are positioned absolutely according to their status classes positioned on the left: 0 (active), left 100% (not yet shown), and left: -100% (already done)
What happens now is that when I switch classes to show a certain page, the page container 'jumps to the left'. In Chrome nearly -100% in Firefox about -70% same in Safari.
Those values are my guess because when I open the dev-tools, nothing is to be found in the styles, in the computed values anywhere.
When I move back to the previous page the container jumps back to its original position, and if I move again to the critical page it stays.
I do no positioning whatsoever with JavaScript anywhere, I only switch classes on HTML elements.
After hours of experimenting back and forth, I found out that the problem is in some way JavaScript-related anyhow.
Using the exact same CSS and HTML with a slightly older version of JavaScript does not show the strange behavior. The changes in the Script are mostly ES2020-module related, and the new version does nothing even remotely related to DOM manipulation different from the older working version.
When not using transitions, the shift of the container does not occur.
Has anyone come across something similar?
Does anyone know of other tools to deeper analyze the current layout state of a page more than the respective developer tools of the browsers?
Any other ideas?
Today I found a solution and at least some kind of explanation, but I still have to investigate some more to truly understand the why and how. I'll post an update if I find a better explanation.
The problem has to do with a text field and focus.
The page in question has a text (search) as its main component.
[I am aware and always was that browsers try to move focused elements into view, regardless of what the author's CSS says.
Therefore, when I decided to give focus to the text field which it does not have on its own, as every page movement required a button to be clicked, I did so on transitionend. This has never changed.
When the issue first occurred, one of the things I tried first was to disable that (auto) focus behavior. It did not solve the problem.
I cannot say what made that change in behavior happen. I change the construction of the page to include a grid some time before the issue occurred. That in itself was not the reason, however (it worked for quite some time with that system, and removing it did not sole the behavior).]
What solved the issue was to initially fully disable the text field and only enable it on transitionend (then focusing it).
The reason browsers moved the page to different positions likely has to do with this situation, as the text fields width is ch based.
The important takeaway (for now) for me is, that there is no hint to be found in the developer tools when the browsers moves - elements in the (in my case unsuccessful) attempt to keep inputs in the viewport.
I think that this should be changed/fixed.
I will as soon as I have the time try to better understand the things that made the problem occur, If someone has information or experience with similar situations pleas add useful hints and background info.

How to determine whether an element is displayed inline or as a block in JavaScript?

The problem: Given a HTML element and potentially some children, can you (and how can you) determine whether it is or will display it's children in a left/right flow (inline) or top-bottom flow (block)?
This problem comes up, e.g., when you want to display a 'dropcursor' that shows where an element can be dropped, as is done by prosemirror-dropcursor. The cursor should be shown as a vertical bar if the elements are in inline flow, or as a horizontal bar above/below the elements if they are in block flow. You can see the same behavior in any text editor if you try to drag & drop things into it.
There are a few solutions that are perhaps less than perfect:
You can look at the type of HTML element and it's defaults. Prosemirror does something like this by relying on the schema of the data being displayed, and it's tricked when you don't display the content in a way consistent with the model. CSS can of course override this.
Using getComputedStyle() to look at the .display and other properties, in a way mimic what the browser rendering algorithm is doing. But that seems potentially awfully complicated and somewhat error prone - consider CSS flexbox, grid, etc.
You can look at the children element's relative position and infer which direction the flow is, but again, that won't work if you have zero or one elements, and may have corner cases anyways.
I was just wondering if it was possible to get this kind of thing directly from the browser, or if there was a robust and/or ready-made way to do it.

How come that javascript reads element that has display:none?

For example if we have:
<style>
.child {display:none;}
</style>
<script>
$('.parent:contains("Invisible")').addClass('newparent');
</script>
<div class="parent">
<div class="child">Invisible</div>
</div>
This code works! Parent div will receive new class newparent. This has no logic to me because I always believed if I put display:none that this is it, element is gone. You can't find it in inspect element, view source, etc.
But obviously this is not the case if javascript can find it. That means that this element is rendered somehow. So I'm wondering if element with display:none is still out there is it affecting performance?
For example if we have right sidebar and we decide to hide it on mobile with display:none.
From experience I know that the site will load faster if sidebar has display:none, but question is still the same, what happens to the element with display:none, is it rendered somehow, if yes how and where?
You seem to have some misconceptions about display:none. It is a css property which causes the element to take up no room on the page. The element is still rendered and still exists all the same.
MDN display
I always believed if I put display:none that this is it, element is gone. You can't find it in inspect element, view source, etc.
Your assumption is incorrect. The element is still part of the DOM. It's just styled to not be rendered visibly on the screen.
So I'm wondering if element with display:none is still out there is it affecting performance?
No more than any other element would. If you have so many elements as to affect performance, then you'd certainly want to address that. But it has little to do with the styling.
what happens to the element with display:none, is it rendered somehow, if yes how and where?
It's part of the structure of the DOM in memory. Everything about it is still there. It's just not visibly shown in the viewport.
CSS styling doesn't change the structure of the HTML. It just governs how that structure is visibly displayed on the screen. (Or in some other medium.) JavaScript, on the other hand, can be used to modify the DOM in-memory, and those changes are also reflected in the display. (As your test demonstrates.)

Why dynamic css may not apply immediately

NOTE: I could not replicate the issue in jsfiddle or jsbin, so unfortunately I will demonstrate the issue only via screenshots.
In my work project some JavaScript control is not rendering properly.
I found that it renders properly if I wrap the rendering logic in setTimeout(renderLogicFunction, 30);. Number 30 was found during experiments. If value is less than 10 it always renders incorrectly. If it is greater than 30 it is always correct. For 10-30 it is pretty random.
I started to debug the rendering logic side-by-side and found that one of the columns has wrong width
However in good rendering
Inner HTMLs for both of those controls are the same.
Let's see when the 16px came from
This refers to the inline style
Then I checked that the bad rendering page also has this inline style but for whatever reason it is not applied yet.
If I let debugger go, I can check that the CSS rule was already applied but it's too late as the column width was taken during calculations for rendering and its current width is not being taken into account anymore. The only way to fix it is to trigger control's refresh. But I think it is not elegant at all.
Do you have any ideas why that happens?
When you need a style to become inmune to overwrite, and make it able to overwrite previous rules of the very same style, you can add it !important
div { width:100%; }
div { width:50%; }
Will render your div elements at 50% width, while
div { width:100% !important!; }
div { width:50%; }
will render your div elements at 100%.
If you use this wisely on your CSS styles you'll probably be able to fix your problem.
I guess you are using some 3th party library which resizes columns.
Instead of setTimeout(renderLogicFunction, 30); it could probably be replaced with jQuery's document ready, https://learn.jquery.com/using-jquery-core/document-ready/

Is it bad to not remove elements from HTML that aren't visible?

I've made a slideshow using JQuery which at the moment just uses append() to add an <img> to a container that was previously defined. The slideshow automatically rotates through, returning back the the start after the final slide and continuing infinitely.
At the moment, I don't remove the previous image in the container at all. I haven't noticed anything change in terms of performance or my memory filling up - a behaviour that I'm used to in Flash if I were to continue adding elements without removing old ones.
Is it necessary to remove the old images, or are these never going to cause performance issues?
Some of this might be browser-dependent, but in general I would say that yes it is indeed "bad" not to clean up your old elements. Whether or not an element is visible, it is still adding a node to the structure of the DOM, and you cannot add to the DOM infinitely.
Unless perhaps the browser implements some sort of intelligent pruning algorithm that swaps out unused/non-visible portions of the DOM, but I've never heard of such a thing being done in practice.
Most likely, it will affect performance over time, the more photos added, the more the performance will suffer, but if at all possible, test it out, add as many as you can, but if there is not a whole lot going on in your site, you may not see any performance issues. if you don't see any issues, don't worry about it. like i said, try it out.
Shouldn't adding $(div).innerHTML='' before appending the image clear everything off in the div?
The browser caches any images that are loaded. Each image does consume memory but removing the images won't affect the cache. If the cache starts to become a problem, the browser will start freeing up memory. Each browser does this differently and some do it better than others. Any image that is not visible in the viewable space of the current page is fair game. If an image on the current page is thrown out and subsequently made visible in the viewable area of the page it is reloaded.
In summary, removing the old images won't affect performance.

Categories

Resources