Right now we currently have two different CSS styles in modules/system/system.css to hide elements if JavaScript is enabled: no-js and js-hide:

html.js .no-js {
  display: none;
}

/*
** For anything you want to hide on page load when JS is enabled, so
** that you can use the JS to control visibility and avoid flicker.
*/
html.js .js-hide {
  display: none;
}

I think the .js-hide is a better description and easier to understand, so I propose that we remove the .no-js style. It's also too bad we don't have a way to do a 'js-show' class...

Comments

dave reid’s picture

Status: Active » Needs review
StatusFileSize
new1.67 KB

Patch to remove the no-js style ready for review.

dave reid’s picture

Title: Duplicate system.css classes: no-js and js-hide » Duplicate system.css classes: no-js and js-hide, add general .hide class
StatusFileSize
new1.92 KB

There's also no good way just to use display: none on something I want hidden. Quick addition to #1 adds the class .hide in addition to .js-hide.

dave reid’s picture

Title: Duplicate system.css classes: no-js and js-hide, add general .hide class » Duplicate system.css classes: no-js and js-hide, add js-show and .hide
StatusFileSize
new2.62 KB

And a final revision that adds a 'js-show' that will hide items if JavaScript is disabled. Too bad CSS3 isn't widely adopted enough to just use:

html:not(.js) .js-show {
  display: none;
}

Status: Needs review » Needs work

The last submitted patch failed testing.

dave reid’s picture

Status: Needs work » Needs review
StatusFileSize
new2.67 KB

Re-rolled to HEAD.

moshe weitzman’s picture

Status: Needs review » Reviewed & tested by the community

Works for me. Nice little cleanup. Thanks.

dries’s picture

It is not clear why we needed to introduce js-show? Care to explain?

dave reid’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new3.03 KB

It's provided to show an element if JavaScript is enabled, as an opposite to js-hide, which hides elements if JavaScript is enabled. I've improved the documentation for it.

moshe weitzman’s picture

For example, the progress bar in upload or the teaser checkbox thing could be emitted with js-show class so that they are only visible if user has js enabled.

dmitrig01’s picture

Why not do this for js-show

.js-hide { display: none; }
html.js .js-show { display: block; }
dave reid’s picture

I'm not sure how that would work with an element that had something like:
<div class="js-show" style="display: inline;">...</div>

dave reid’s picture

catch’s picture

Issue tags: +CSS, +JavaScript

Status: Needs review » Needs work

The last submitted patch failed testing.

dave reid’s picture

Status: Needs work » Needs review
Issue tags: +Quick fix

HEAD testing failure. Resetting.

cburschka’s picture

Status: Needs review » Needs work

1.) Patch doesn't apply to system.js anymore, so a reroll is required.

Additional comments:

2.) The CSS spec tells browsers to ignore selectors it doesn't understand, if I remember correctly. Therefore, even if CSS3 is not widely supported, it may be not be a bad idea to add the html:not(.js) (properly documented, of course) to remove the "flicker" the comment mentions, at least for browsers that do support CSS3.

3.) <div class="js-show" style="display: inline;">...</div>

Shouldn't direct style attributes be avoided in favor of classes anyway?

dawehner’s picture

StatusFileSize
new3.24 KB

here is a fast rerole.

not sure about the inline stuff/css3, but what about creating a inline class?

dawehner’s picture

Status: Needs work » Needs review

needs review...

cburschka’s picture

Status: Needs review » Reviewed & tested by the community

Those duplicate asterisks in the comment block are pretty odd. They were already in there though, so let's leave them for another issue to fix.

I'm sceptical as ever about relying on the html.js class to do anything serious (how can you trust the server to accurately tell the client whether the client is executing Javascript at the moment? What if you switch it off or on while browsing?). But as it seems to be done throughout core, we might as well do it here too.

Status: Reviewed & tested by the community » Needs work

The last submitted patch failed testing.

aspilicious’s picture

Status: Needs work » Fixed
html.js .no-js {
  display: none;
}

/*
** For anything you want to hide on page load when JS is enabled, so
** that you can use the JS to control visibility and avoid flicker.
*/
html.js .js-hide {
  display: none;
}

doesn't exist anymore in system.css

dave reid’s picture

Status: Fixed » Needs work

What about .js-show?

aspilicious’s picture

There aren't any js elements left...

/*
** Floating header for tableheader.js
*/
table.sticky-header {
  margin-top: 0;
  background: #fff;
}

is the only js thing you can find

dave reid’s picture

Title: Duplicate system.css classes: no-js and js-hide, add js-show and .hide » Add js-show CSS class for hiding elements when JavaScript is disabled

system.behaviors.css:

/**
 * For anything you want to hide on page load when JS is enabled, so
 * that you can use the JS to control visibility and avoid flicker.
 */
html.js .js-hide {
  display: none;
}

This still needs a .js-show opposite. Clarifying title since part of the issue was taken care of.

aspilicious’s picture

Ow fok srry opened wrong file (system.css), I'm so stupid!

Thnx dave... :(

aspilicious’s picture

Can't we do something easy as like dimitri said?

html.j .js-show {
display: block
}
dave reid’s picture

That wouldn't work because the point would to be to hide the element if JavaScript is disabled. Also see my #11.

robloach’s picture

Oh, I've been trying to get this one in for a while.

dave reid’s picture

Version: 7.x-dev » 8.x-dev

Bumping to D8.

robloach’s picture

Adding to my ever growing things of things I'd like to eventually look at.

robloach’s picture

Status: Needs work » Needs review
StatusFileSize
new2.27 KB

There we go!

robloach’s picture

StatusFileSize
new2.23 KB

Looks like system.js is not included everywhere, so this should live in drupal.js instead.

ohnobinki’s picture

+1

mrfelton’s picture

The title of this issue is "Add js-show CSS class for hiding elements when JavaScript is disabled". Yet what this patch does is to allow you to :

* Use the class 'js-hide' to hide an element if JavaScript is enabled.
* Use the class 'js-show' to show an element only if JavaScript is enabled.

What about hiding an element only if JavaScript is disabled, as per the issue title? For that, wouldn't you need a no-js-hide class, something like:

html.no-js .no-js-hide {
   display: none;
 }
twod’s picture

What about hiding an element only if JavaScript is disabled, as per the issue title?

+/**
+ * Show elements with the 'js-show' class. These elements will not be shown if
+ * JavaScript is disabled.
+ */
+Drupal.behaviors.jsShow = {
+  attach: function(context, settings) {
+    $('.js-show', context).show();
+  }
+};
...
+html.js .js-hide, .js-show {
   display: none;
 }

@mrfelton, that's your use case right there. Things with .js-show start out with display: none;, which JavaScript switches to an display: block; style on the element itself, overriding the stylesheet. No script, no unhiding.

ksenzee’s picture

Status: Needs review » Reviewed & tested by the community

This looks correct to me.

I'm actually tempted to move it to a bug report, because currently we're showing the line about 'You can insert the delimiter "<!--break-->" (without the quotes) to fine-tune where your post gets split' even when JS is enabled, which is incorrect and confusing.

tim.plunkett’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/misc/drupal.jsundefined
@@ -383,4 +383,14 @@ Drupal.theme.prototype = {
+    $('.js-show', context).show();

Aren't we doing $(context).find('.js-show').show(); now?

nod_’s picture

indeed.

Just to play the devil's advocate: a style tag with .js-show {display:none;} wrapped in a noscript tag will work too (it's valid HTML). Not suggesting we do that, just bringing it up.

ksenzee’s picture

Hm. Wrapping .js-show {display:none;} in a noscript tag would be a good approach. With the existing patch you have the slight possibility of users seeing the js-only content pop into place after the rest of the page structure is there already. It also adds yet more JS to Drupal.behaviors, and goodness knows we have enough already. The noscript tag avoids both those problems.

So it sounds like a fine plan—except that I have no idea how to implement it sanely. All I can think of is adding another flag to the $options parameter in drupal_add_css(), which does not really appeal. That's such a complicated function already. Unless someone thinks that's actually a good idea, or has a better one, I'd say we stick with the existing patch.

zhangtaihao’s picture

Not that this is any more sane, but I presume drupal_add_html_head() has been looked at and specifically ignored?

robloach’s picture

I'd rather not have this stuff presented inline within the HTML of the document. We would benefit of aggregation and performance if this was in .css and .js files.

tstoeckler’s picture

Status: Needs work » Closed (duplicate)

This is now being handled as part of #1848064: Allow to filter modules by arbitrary search strings on the Modules page. Since this has been inactive for quite a while, marking this as duplicate.

dave reid’s picture

Version: 8.0.x-dev » 7.x-dev
Issue summary: View changes
Status: Closed (duplicate) » Needs work

I hate when things get closed and fixed in Drupal 8 but never considered for backport to D7 which is where I want to be using this functionality *now*.

ksenzee’s picture

Status: Needs work » Needs review
StatusFileSize
new1.17 KB

Here's a reroll for the js-show part, which is still sensible for D7.

Status: Needs review » Needs work

The last submitted patch, 44: 335185-44.js-show.patch, failed testing.

Status: Needs work » Needs review

ksenzee queued 44: 335185-44.js-show.patch for re-testing.

dave reid’s picture

StatusFileSize
new508 bytes

Re-rolled for the D8-non-js solution.

Status: Needs review » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.