Hi, I have some JS that manipulates the DOM to show / hide certain elements when needed. It works perfectly when the event handler is fired (click event). The problem is that when I refresh the page by clicking the reload button that every browser has: the CSS gets all messed up for pretty much everything.
The only way it becomes perfect again is if I click a link to the page that same JS is on.
When I comment the following JS out, then there is no problem when refreshing. So I know that is where the problem is. It's as if the browser is caching the DOM so it conflicted with the changes made before the page was refreshed, then reapplied incorrect styling on refresh.
I have the cache disabled in the dev tools: right click > Inspect > Network > Disable cache is turned on.
I've also done ctrl+f5
using a chrome based browser, and nothing worked.
html
EDIT: note that this html is very basic to get the point across, there is much more like some label tags, etc, but I've checked the css / html of the page in question after loading (and having the errors), and there is no difference in the html structure than it was before. For the answer I selected, I'd like to add it might also be a browser bug.
...
<link type="text/css" rel="stylesheet" href="/my.css" />
...
...
<form>
<p>1</p>
<p>2</p>
<p>3</p>
</form>
my.css
form > p {
position: absolute; /* hide most p's that will be shown when event is fired */
right: -1000px;
}
form p:first-of-type {
position: static; /* first p element is not hidden */
}
EDIT: in the answer I selected, I commented that top: -500px;
works fine with the JS used below, but right: -1000px;
gives me the problem I'm saying. I can click refresh, and the page loads properly every time. So there's probably a browser bug as I said above.
my.js
// Running from a click event, leaving it out to show less code
var form_p_wrappers = document.querySelectorAll('form > p');
for (var i=0; i < form_p_wrappers.length; i++) {
form_p_wrappers[i].style.position = 'static'; // make form p's visible
}
I know it's generally not good practice to do obj.style.x = 'value';
... Adding / removing a class is usually much easier, and has never given me a problem (in fact, that works fine here)...
But I came across this problem recently, and in this case, doing it the above way was quicker and easier to write, if it worked the way I wanted...
Does anyone know why it's not properly showing the CSS as I'd expect, unless I click a link to the page?? Again, it's loading, it's just not presenting properly. Same thing with the inline edits made via JS: there are no visible inline edit in the DOM when I refresh the page, but it's still wonky.
Is there is a way to make it work the way I want without adding a class?? Again, adding / removing a class works perfectly, but in this instance, writing it the above way was quicker. I just want to know WHY it didn't work the way I expected.
Thanks!
It sounds like the issue you’re seeing is due to how JavaScript is interacting with your CSS, especially when you’re setting styles directly on elements. This can sometimes lead to unexpected behavior when the page is refreshed.
What’s Happening:
When you use element.style.position = 'value';, you’re applying inline styles directly to the element, which will override any external CSS. This can cause conflicts, especially on page reloads, since the browser might be reapplying those inline styles too early or in a way that messes with your CSS layout.
On the other hand, when you navigate by clicking a link, the page reloads cleanly, and the CSS gets applied correctly without any interference from JavaScript. But a browser refresh sometimes doesn’t fully reset everything in the same way, leading to the CSS breaking.
Solutions You Can Try:
Switch to Using Classes While you mentioned that adding/removing a class works, it really is the best practice. By toggling a class, you avoid overwriting styles inline and instead let the CSS handle everything:
form_p_wrappers[i].classList.add('visible');
And in your CSS:
.visible {
position: static;
}
This will ensure your styles remain intact on reload.
Delay Your JavaScript Until the Page Is Fully Loaded Another thing to try is making sure your JavaScript runs only after the page (and all CSS) has fully loaded. Sometimes, JS can execute too early and cause styling issues. You can use the window.onload event for that:
window.addEventListener('load', function() {
var form_p_wrappers = document.querySelectorAll('form > p');
for (var i = 0; i < form_p_wrappers.length; i++) {
form_p_wrappers[i].style.position = 'static';
}
});
This ensures that your JS won’t run until everything is properly loaded.
Clear Inline Styles on Refresh If you really want to stick with your current approach and just fix the refresh issue, you could clear any inline styles on page load:
window.addEventListener('load', function() {
var form_p_wrappers = document.querySelectorAll('form > p');
for (var i = 0; i < form_p_wrappers.length; i++) {
form_p_wrappers[i].removeAttribute('style');
}
});
This will reset the elements back to their default styles before you apply any new changes with JavaScript.
Why This Happens:
In short, it’s likely that the browser’s refresh is reapplying the inline styles before the external CSS fully loads, causing things to break. Switching to classes or delaying the JS can help avoid this.
Hope this helps! Let me know if you need more info or clarification.