There are about 20 styled articles (5-10 pages each with inconsistent sections) I need to display in my app. Without having to manually write components for each of them, we've started to export HTML from a Google Doc where they're hosted and display in an iframe. While this mostly gets what we need, there's some inconsistent styling and other changes I'd like to address.
I've started writing a JS script (node.js) that will consume all of the HTML files and try to format them correctly but having issues finding a correct library to do this.
I've tried using Jsoup, jsdoc, node-html-parser, and finally landed on cheerio.
What I'm stuck on is targeting dynamically generated classes based on their attributes and changing them. For instance, I'm trying to make changes to the superscripts in the HTML and the only thing I have to go off of is the attribute 'vertical-align'.
.c3 {
vertical-align: super;
font-size: 10pt;
}
Note that the class c3 is dynamically generated so we can't search off of that. But basically I'd want to target it and then change all of the class attributes to something like:
.c3 {
font-size: 6pt;
vertical-align: baseline;
position: relative;
top: -0.4em;
}
Does anyone have any recommendations on how to handle something like this? I have to do some more complicated things in the script like target img elements, and modify classes for those elements and their parents. Any library suggestions would be appreciated, because Jquery doesn't seem like the right tool for this.
Note: CSS is inline within the HTML file within tags
"Note: CSS is inline within the HTML file within tags"
Based on that, one way would be to loop through all elements with a style attribute using querySelectorAll, and then see if any of those with inline css contain the target style. You could then remove the inline styles and apply a class. The more you can narrow the query selector the better this will perform.
document.querySelectorAll("[style]"); all elements with a style attribute.
document.querySelectorAll("div[style]"); all div elements with a style attribute.
var elements = document.querySelectorAll("[style]");
for (let i = 0; i < elements.length; i++) {
style = elements[i].getAttribute("style");
if (style.includes("vertical-align")) {
console.log( elements[i].getAttribute("style") ); //original
elements[i].removeAttribute("style");
elements[i].classList.add("replacementClass");
console.log( elements[i].getAttribute("style") ); //empty
// or instead of a class if you want to just update the style
elements[i].setAttribute('style','font-size: 6pt; vertical-align: baseline; position: relative; top: -0.4em;');
console.log( elements[i].getAttribute("style") ); //inline
}
}
.replacementClass {
font-size: 6pt;
vertical-align: baseline;
position: relative;
top: -0.4em;
}
<span id="test" style="vertical-align: super; font-size: 10pt;">oh boy</span>
Removing the inline style might be the only way because if the inline css isn't removed it will override any classes you apply to it. You could end up with quite a few "rules" to apply based on this method though.
Related
I'm creating a web app and need to decide on a consistent way to style my elements. I noticed that a lot of help online uses classes but I have generally used attributes (like the query selector [my-attr]) to style multiple elements, since I don't have to work with classList and can remove and set attributes very easily.
Using no external libraries, why would people use classes to style their elements over attributes? It seems like attributes can do everything classes can do but better, since you can also assign values to the attributes as well. I also haven't seen any discussion on performance differences anywhere, making me believe that attributes should be more appreciated than they are in tutorials on styling pages.
Any thoughts on instances where classes could do a better job than attributes at something would be greatly appreciated, even if the arguments are subjective and come down to some sort of preference!
Thanks!
Again, this is for vanilla javascript, HTML, and CSS. I understand that libraries like jQuery may make it easier to use classes, but I don't plan on using any libraries.
It's more consistent, is the end-all be all, truthfully. If you'd rather use attributes, go for it. However it makes it just that much more difficult for anyone who has to help you out later. CSS classes are designed for grouped selection and application of common styles. CSS just happens to also be able to select attributes as well, because it does make sense in some edge cases.
Generally, attributes should be reserved for anything non-style related that adds a value for a different use, be it screen-readers or variable containers for JavaScript, such as data-id="34" may let you make an asynchronous request with the ID parameter.
Consider this example, it's got some simple "class" based buttons:
.button {
display: inline-block;
border: 1px solid;
padding: 4px 10px;
text-decoration: none;
margin-bottom: 4px;
}
.primary {
background: currentColor;
}
.primary span {
color: #fff;
}
.blue {
color: #0095ee;
}
.red {
color: #ee3300
}
Red Button
<span>Red Button</span>
<br />
Blue Button
<span>Blue Button</span>
To replicate something like this with attributes, we'll be doing something like this with some obnoxious and rather arbitrary attribute names. Doing this I actually messed up because I used the wrong attribute name and value pair in one case.
[type="button"] {
display: inline-block;
border: 1px solid;
padding: 4px 10px;
text-decoration: none;
margin-bottom: 4px;
}
[status="primary"] {
background: currentColor;
}
[status="primary"] span {
color: #fff;
}
[color="blue"] {
color: #0095ee;
}
[color="red"] {
color: #ee3300
}
Red Button
<span>Red Button</span>
<br />
Blue Button
<span>Blue Button</span>
Does it not make more semantic sense to keep all your stylistic and group target attributes inside the class attribute? I mean, that's what it was designed for. I suppose you could drop the parameter value and just use parameter names, but you're really defeating the purpose of attributes, considering class is a Global Attribute in and of itself.
Here's a JavaScript example as well:
let classes = document.getElementsByClassName('button');
for( i = 0, n = classes.length; i < n; ++i ){
classes[i].style.background = 'red';
}
let attrs = document.querySelectorAll('[button]');
for( i = 0, n = attrs.length; i < n; ++i ){
attrs[i].style.background = 'blue';
}
a {
padding: 10px;
margin-bottom: 4px;
display: inline-block;
text-decoration: none;
color: #fff;
}
<a href="#" button>Attr 1</a>
<a href="#" button>Attr 2</a>
<a href="#" button>Attr 3</a>
<br />
Class 1
Class 2
Class 3
Putting aside the fact that JS has immense integration with class (and id) based functions for selectors, you have to use querySelector and querySelectorAll for the attribute buttons.
While not inherently a bad thing, (honestly I prefer querySelector over getElement(s)By… in general), but when you look at it, querySelectorAll('[button]') just does not read well, almost like I'm targeting a <button> element. Semantically it makes it harder to read than:
getElementsByClassName('button') - Clearly getting all elements that have a button class, or even
querySelectorAll('.button') - Since the . is universally understood as the "class" selector, and everyone working with HTML, CSS, and JS learns that on literally day 1 of any web development program/tutorial. So you're throwing a bit of a wrench into the project by removing such a fundamental piece of it.
I'm sure you've heard the phrase "Just because you can, doesn't mean you should." - I think that applies perfectly here. I mean, we actually used to use things like <font color="red">Red</font> and we moved away from it because it made more sense to group styles in a single Global Attribute. There's nothing stopping you, but I think it's asking for more trouble than it's worth to drop classes for arbitrary parameter names, not to mention if you have an issue and post your code for help, the first response will always be "Why are you doing that, what preprocessor are you using?"
I think it's just the functional probl, if you want to give style u should use class, but if you want to modify u can use query selector cause it will not added an inline style on your html and you can minify the script.
we can create style or any other tag with
var st = document.createElement("style");
and even append the same to body
body.append(st);
and it will create
<body><style></style></body>
I wanna know can we put style in style tag with javascript as well not simple rules, I know there is $("selector").css() function is there which can apply css rules to selector but i want a bit more powerful rule and I want to add in style tag i just created,
something like this:
<style>
div.bar {
text-align: center;
color: red;
}
</style>
st.innerHtml or st.innerText are not letting me set these values.
Note: This was asked me to do in Browser Console only.
You can simply use jquery .text method like
const cssCode = `div.bar {
text-align: center;
color: red;
}`
$('style-tag-selector').text(cssCode)
but in my opinion, whetever your goal is - this solution is not ok. You shouldn't mess with CSS via JavaScript.
Best approach is to have styles in separately loaded .css file and then you can toggle classes to elements with javascript.
You can add your css directly within the style tag and append them to the head of your page:
$( "head" ).append( "<style>div.bar {text-align: center; color: red}</style>" );
You can append multiple style tags with css in the head beneath each other, in this way you can override previous syles, but it is not best practice.
I prefer having your styles in separate files and to manage wether or not the files will be included in your code.
Actually there's an interface for this. For example, add a style element and add a rule to it (this will result in anything with the class should-be-red to be red.
var styleElement = document.createElement('style');
document.head.appendChild(styleElement);
var sheet = styleElement.sheet;
sheet.insertRule('.should-be-red { color: red; }', 0);
You can iterate over the rules and insert/delete rules and exciting things like that.
More info: https://developer.mozilla.org/en-US/docs/Web/API/CSSStylesheet
jsbin: https://jsbin.com/jodiro/1/edit?html,js,output
I am doing a code that do some js injection of code in page, with JQuery. But in my input that i get in some pages modify it, I am putting all important attributes and define them as !important, but it's impossible to put all the attributes in all the tags.
Someone know how to disable all other css inside a div?
Solution I think:
I found a solution but i don't want to use it. Its eliminate al css from the page, while i am injecting the code after using that code I eliminate my css and code and apply the original code from the webpage
Thanks
If you're using that many !importants you're doing it wrong.
The solution to this problem is to properly organize your css. Important stuff last, because it overrides what was previously styled. Also use your selectors wisely. Example:
<a class="link">Link</a>
.
a:link { color: red; }
.
.
.
.link { color: green !important; } // Nop
a.link { color: green; } // Yup
If you override everything it will work with normal CSS rules on every page. Not what you were hoping for, but it is a solution.
css:
#myInsertDiv {
color: blue;
padding: 0;
margin: 0;
background: white;
border: 0px;
/* etc you have to restyle EVERY possible value */
}
html:
<div id="myInsertDiv"></div>
The main issue is you have to style every attribute, and reset everything else to a default value.
Or you can insert all the style information into the style attribute on the div, but that is probably doing it wrong too.
If I got you right you can use jQuery for modifying CSS properties on any elements of the page (huh), using something like this $('.Myclass').css('color','#ff0000')
And more about selectors in jQuery - http://api.jquery.com/category/selectors/
This question already has answers here:
How to reset/remove CSS styles for a specific element or selector only
(17 answers)
Closed last month.
I know this question was asked before, but before marking it as a duplicate, I want to tell you that my situation is a little different from what I found on the internet.
I'm building and embedded script that people can put it on their sites. This script creates a div with a certain width/height and some information in it.
My problem is that some websites declare styles for div that are inherited by my div as well.
for example:
div{
background-color:red;
}
so if I don't set any background color to my div, it will show red even if I don't want that.
The only solutions I come along is to overwrite as many css proprieties, this way my div will show exactly as I want.
The problem with this solution is that there are too many css proprieties to overwrite and I want my script to be as light as it can be.
So my question is if you know another solution to my problem.
It can be in css/javascript /jQuery.
Thanks
"Resetting" styles for a specific element isn't possible, you'll have to overwrite all styles you don't want/need. If you do this with CSS directly or using JQuery to apply the styles (depends on what's easier for you, but I wouldn't recommend using JavaScript/JQuery for this, as it's completely unnecessary).
If your div is some kind of "widget" that can be included into other sites, you could try to wrap it into an iframe. This will "reset" the styles, because its content is another document, but maybe this affects how your widget works (or maybe breaks it completely) so this might not be possible in your case.
Only set the relevant / important CSS properties.
Example (only change the attributes which may cause your div to look completely different):
background: #FFF;
border: none;
color: #000;
display: block;
font: initial;
height: auto;
letter-spacing: normal;
line-height: normal;
margin: 0;
padding: 0;
text-transform: none;
visibility: visible;
width: auto;
word-spacing: normal;
z-index: auto;
Choose a very specific selector, such as div#donttouchme, <div id="donttouchme"></div>. Additionally, you can add `!important before every semicolon in the declaration. Your customers are deliberately trying to mess up your lay-out when this option fails.
You could try overwriting the CSS and use auto
I don't think this will work with color specifically, but I ran into an issue where i had a parent property such as
.parent {
left: 0px;
}
and then I was able to just define my child with something like
.child {
left: auto;
}
and it effectively "reset" the property.
Technically what you are looking for is the unset value in combination with the shorthand property all:
The unset CSS keyword resets a property to its inherited value if it inherits from its parent, and to its initial value if not. In other words, it behaves like the inherit keyword in the first case, and like the initial keyword in the second case. It can be applied to any CSS property, including the CSS shorthand all.
.customClass {
/* specific attribute */
color: unset;
}
.otherClass{
/* unset all attributes */
all: unset;
/* then set own attributes */
color: red;
}
You can use the initial value as well, this will default to the initial browser value.
.otherClass{
/* unset all attributes */
all: initial;
/* then set own attributes */
color: red;
}
As an alternative:
If possible it is probably good practice to encapsulate the class or id in a kind of namespace:
.namespace .customClass{
color: red;
}
<div class="namespace">
<div class="customClass"></div>
</div>
because of the specificity of the selector this will only influence your own classes
It is easier to accomplish this in "preprocessor scripting languages" like SASS with nesting capabilities:
.namespace{
.customClass{
color: red
}
}
Try this: Create a plain div without any style or content outside of the red div. Now you can use a loop over all styles of the plain div and assign then to your inner div to reset all styles.
Of course this doesn't work if someone assigns styles to all divs (i.e. without using a class. CSS would be div { ... }).
The usual solution for problems like this is to give your div a distinct class. That way, web designers of the sites can adjust the styling of your div to fit into the rest of the design.
As long as they are attributes like classes and ids you can remove them by javascript/jQuery class modifiers.
document.getElementById("MyElement").className = "";
There is no way to remove specific tag CSS other than overriding them (or using another element).
you may use this below option.
<style>
div:not(.no_common_style){
background-color:red;
}
</style>
now , if their any place where you do not want to apply default style you can use 'no_common_style' class as class.
ex:
<div class="no_common_style">
It will not display in red
</div>
From what I understand you want to use a div that inherits from no class but yours. As mentioned in the previous reply you cannot completely reset a div inheritance. However, what worked for me with that issue was to use another element - one that is not frequent and certainly not used in the current html page. A good example, is to use instead of then customize it to look just like your ideal would.
area { background-color : red; }
One simple approach would be to use the !important modifier in css, but this can be overridden in the same way from users.
Maybe a solution can be achieved with jquery by traversing the entire DOM to find your (re)defined classes and removing / forcing css styles.
I'm using sifr for the first time today. I have it up and running; however, I need some help. Rather than explain, I'll show you the code below:
<div id="pullquote">“Fantastic property, facilities and location. We
couldn’t have asked for more!” <em>Mr & Mrs. Smith</em></div>
So far, so good. I have then styled that in the same document in case flash/JavaScript is disabled. No problem.
sIFR.replace(journal, {
selector: 'div#pullquote',
wmode: 'transparent',
css: [
'.sIFR-root { text-align: center; color: #be7705; font-size: 30px; background-color:#fdefd4; }',
'em { font-style: normal; color: #1d5d69; font-size: 26px; }']
});
That's what is included in my JavaScript file. Am I correct in styling the element like this? I got slightly confused with the selector, then using a second selector within js-css. Once again, there is also sifr.css. What should be included in this document? Should I be styling the element here?
I suppose my question is: What should be included, and what styling should be done in sifr-config.js and what styling should be done in sifr.css?
Thank you :)
In the CSS for the HTML page (sifr.css) you can add a style to hide the elements that sIFR will replace before does so, and you can do some tuning of the text so the text size maps better to the Flash font.
The selector parameter for sIFR.replace() is used to select the elements you wish to replace by sIFR.
The css parameter contains the CSS used inside the Flash movie. At this point, all CSS selectors are relative to the element you replaced, so if you replace an h1#foo, then you select em rather than h1#foo em. This is the only place you can style the text inside the Flash movie, aside from font size, which, if not specified here, is derived from the font size of the replaced element.