How to Use Non Existing CSS Classes

Can I use non existing CSS classes?

"CSS class" is a misnomer; class is an attribute (or a property, in terms of scripting) that you assign to HTML elements. In other words, you declare classes in HTML, not CSS, so in your case the "target" class does in fact exist on those specific elements, and your markup is perfectly valid as it is.

This doesn't necessarily mean that you need to have a class declared in the HTML before you can use it in CSS either. See ruakh's comment. Whether or not a selector is valid depends entirely on the selector syntax, and CSS has its own set of rules for handling parsing errors, none of which concern the markup at all. Essentially, this means HTML and CSS are completely independent of each other in the validity aspect.1

Once you understand that, it becomes clear that there is no side effect of not defining a .target rule in your stylesheet.2 When you assign classes to your elements, you can reference those elements by those classes either in a stylesheet, or a script, or both. Neither has a dependency on the other. Instead, they both refer to the markup (or, more precisely, its DOM representation). This principle applies even if you're using JavaScript to apply styles, as you're doing in your jQuery one-liner.

When you write a CSS rule with a class selector, all you're saying is "I want to apply styles to elements that belong to this class." Similarly, when you write a script to retrieve elements by a certain class name, you're saying "I want to do things with elements that belong to this class." Whether or not there are elements that belong to the class in question is a separate issue altogether.


1 This is also why a CSS ID selector matches all elements with the given ID regardless of whether the ID appears exactly once, or multiple times (resulting in a non-conforming HTML document).

2 The only situation I'm aware of where an empty CSS rule like that is necessary is when some browsers refuse to apply certain other rules properly as the result of a bug; creating an empty rule will cause those other rules to be applied for some reason. See this answer for an example of such a bug. However this is on the CSS side and therefore should have nothing to do with the markup.

How to find classes that are not used in any CSS selector?

Okay, there you go ;)

Take a look at the script I have created, especially getUndefinedClasses function.

function httpGet(theUrl) {  var xmlHttp = new XMLHttpRequest();  xmlHttp.open( "GET", theUrl, false ); // false for synchronous request  xmlHttp.send( null );  return xmlHttp.responseText;}

function getAllCSSClasses(cssdata) { var re = /\.(.+)\{/g; var m; let classes = []; do { m = re.exec(cssdata); if (m) { for(let key in m) { if( (typeof m[key] == "string") && (classes.indexOf(m[key]) == -1) && (m[key].indexOf(".") == -1) ) classes.push(m[key].replace(/\s/g, " ")); } } } while (m); return classes;}
function getAllClasses() { var csses = document.querySelectorAll('link[rel="stylesheet"]'); var classes = [] for (i = 0; i < csses.length; ++i) { // let styledata = httpGet(csses[i].href); var styledata = ".hi{ display: none; }"; var cclasses = getAllCSSClasses(styledata); var classes = Object.assign([], classes, cclasses); classes.concat(cclasses); } return classes;}
function getHTMLUsedClasses() { var elements = document.getElementsByTagName('*'); var unique = function (list, x) { if (x != "" && list.indexOf(x) === -1) { list.push(x); } return list; }; var trim = function (x) { return x.trim(); }; var htmlclasses = [].reduce.call(elements, function (acc, e) { return e.className.split(' ').map(trim).reduce(unique, acc); }, []); return htmlclasses;}

function getUndefinedClasses(cssclasses, htmlclasses) { var undefinedclasses = []; for (let key in htmlclasses) { if(cssclasses.indexOf(htmlclasses[key]) == -1 ) { undefinedclasses.push(htmlclasses[key]); } } return undefinedclasses;}
var cssclasses = getAllClasses();var htmlclasses = getHTMLUsedClasses();
console.log("Undefined classes : " + getUndefinedClasses(cssclasses, htmlclasses))
<!DOCTYPE html><html><head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width">  <title>JS Bin</title>  <link rel="stylesheet" href="hi there"></head><body>  <div class="hi"></div>  <div class="there"></div>  <div class="there_thier_333"></div></body></html>

Detect use of non-existent classNames in CSS Modules/React

If you are open to typescript solution, I found one TS plugin for you.

typescript-plugin-css-modules

It can populate the styles object with type information for available keys.

You don't have to switch whole project to typescript, you can add // @ts-check directive at the top of this file to enable the TS engine design time check.

Non-generated classname selector in css module

It's an old question but the answer is :global() selector in css modules.

For more info: Exceptions - CSS Modules

Example the code:

<div class={styles.myClass}>
<SomeComponentWithOwnCss />
</div>

Output:

<div class="myClass_s4jkdh3">
<div class="SomeComponentWithOwnCss"></div>
</div>

And CSS:

.myClass div:global(.SomeComponentWithOwnCss) {
background-color: red;
}

Working example overhere: codesandbox

Change CSS properties of non-existing elements

One option would be to dynamically create a style element:

$("<style type='text/css'> .redbold{ color:#f00; font-weight:bold;} </style>").appendTo("head")
$("<div/>").addClass("redbold").appendTo("body");

Taken from here: Create a CSS rule / class with jQuery at runtime.

Here's a possible IE alternative (see Creating a CSS class in jQuery):

document.styleSheets[0].addRule('body', 'background: green', -1);

For reference, see the documentation for addRule.

CSS Modules - referencing classes from other modules

This is a common issue when migrating to CSS Modules. In short, a css module cannot override a style from another css module, and this is by design. Styles are supposed to live with the components that render them, and nowhere else.

What you can do to refactor this is to create a component style variant and explicitly set the variant through a prop when rendered within your wrapper.

For example, suppose your headline component currently looks something like this:

CSS

.headline {
color: green;
}

JSX

import styles from "Headline.css";
const Headline = () => {
return (
<div className={styles.headline} />
);
}

Rather than trying to override the .headline class name from somewhere else, you can create a variant class name that you toggle through a prop:

CSS

.headline-green {
color: green;
}

.headline-orange {
color: orange;
}

JSX

import styles from "Headline.css";
const Headline = ({orange}) => {
return (
<div className={orange ? styles.headlineOrange : styles.headlineGreen} />
);
}

And when you render it from your wrapper, set it to the orange variant:

<Headline orange />

Tip: you can use composes to eliminate duplicate common styles between your variants.

Is it poor form to use CLASS attributes with no corresponding CSS rule?

Using CSS classes and - depending on the case - IDs (unique!!) is perfectly fine and often the only solution to keep your HTML code valid while giving additional attributes used by scripts.

While using non-standard attributes often works fine, too, it will prevent your html code from validating and might cause issues in the future.

However, for some cases there might be attriutes which can be used, too - like rel on links which is often used for scripts which modify link behaviour.

http://www.w3.org/TR/html401/struct/global.html#h-7.5.2 also mentions that class is general-purpose:

The class attribute, on the other
hand, assigns one or more class names
to an element; the element may be said
to belong to these classes. A class
name may be shared by several element
instances. The class attribute has
several roles in HTML:

  • As a style sheet selector (when an author wishes to assign style information to a set of elements).
  • For general purpose processing by user agents.

CSS Modules - exclude class from being transformed

Please do not use inline styles as someone else suggested. Stay away from inline styles as much as you can because they can cause unnecessary re-renders.

You should use global instead.

.my-component {
:global {
.external-ui-component {
padding: 16px;
// Some other styling adjustments here
}
}
}

https://github.com/css-modules/css-modules#usage-with-preprocessors

Also, I recommend using camel case style names which is the preferred way for css-modules.
So your class name would be : .myComponent { ... }

And you can use it in your code as

<div className={ styles.myComponent } >

If you wanted to add more styles , you can use the array.join(' ') syntax.

<div className={ [ styles.myComponent, styles.anotherStyle ].join(' ') } >

This is cleaner!



Related Topics



Leave a reply



Submit