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
Is It Correct to Use Alt Tag for an Anchor Link
Is Using <Li> Without Enclosing <Ul> Tags Dangerous
HTML Combo Box with Option to Type an Entry
Why Should I Not Use HTML Frames
Difference Between Url Encode and HTML Encode
What Values for Checked and Selected Are False
Form and File Upload with HTMLservice and App Script Not Working
Why Is a Self-Closing Iframe Tag Preventing Further Dom Elements to Be Displayed
How to Disable CSS in Browser for Testing Purposes
How to Bevel the Corner of a Block Div
How to Vertically Center a Bootstrap Carousel-Caption
How to Get a Web Page Header/Footer Printed on Every Page
How Is the Margin-Top Percentage Calculated
Rendering HTML Elements to <Canvas>