Overwrite jQuery UI CSS - javascript

I have a little problem with jQuery UI at this time.
We use jQuery Accordions for our application and since our upgrade to jQuery UI 1.11.14 we experience a problem that causes any CSS we have written for Accordions to get overwritten by jQuery.
As far as I've understood this, jQuery UI activates itself after pageload and appends its styling. That leaves the question how I can add my own styling if jQuery always comes last. Any style inspectors shows that jquery-ui.min.css overwrites everything we have written before.
I know that !important exists but this is just bad practise and we want to avoid this or else we would append !important to about 20 rules or so which just looks terrible.
Edit:
Here is a screenshot from IE's F12 Console:
Here is a screenshot from IE's F12 Console http://puu.sh/lAoYJ/b3ed91b91c.png

Specificity matters a lot in CSS. Almost all the rules in jQuery UI do not use #ids. So that's a great advantage. ID takes higher precedence. So, when you wanna do something, for eg:
.col-md-5 {color: #f00;}
If this was already written in the bootstrap as:
.row .col-md-5 {color: #000;}
Then your code doesn't work. Give the body an id or a parent. So that way, you can target:
#id .col-md-5 {color: #f00;}
And that works well.

Related

Adding CSS class to div with unique ID

So, I am really new to CSS. I am developing a site for the company I work for using WordPress. I know, WordPress "NOOB ALERT."
Anyway, I am using the massive dynamic theme and was hoping to get some help. I created three CSS classes that I want to apply to three different divs that have unique ID's.
widget-column-1
widget-column-2
widget-column-3
And I want to add the following CSS classes to those divs.
footer-widget-1
footer-widget-2
footer-widget-3
respectively to their corresponding number. However, when I tried any of the following methods using the themes built-in "custom JS" editor, the CSS classes failed to apply to the divs. And yes, the CSS works, I manually added the classes in developer mode on Chrome and it gave me the following.
Screenshot of result w/ css
But, whenever I input any of the following JS solutions, the CSS class is not applied.
$(".widget-column-1").addClass("footer-widget-1");
$("#widget-column-1").addClass("footer-widget-1");
Neither of these worked, I also tried a few other solutions but can't remember them off the top of my head. Please try to keep in mind that I just started CSS two days ago and am still learning, I don't want my poor little head to get bashed in by some coding giant with a club made of XSS attacks.
CSS classes I am trying to apply
Looking at your screenshot, what would work for the first widget would be:
$('[widgetid="footer-widget-1"]').addClass("footer-widget-1");
But, in order for this to work, you'd have to place it in a script that gets loaded on every page you want this to happen. And you probably want to wrap it into a
(function($){
// your jQuery code here...
})(jQuery)
What I don't really understand is why are you trying to add this class, when you could use the existing class/id/attributes as selectors for the CSS you're trying to apply.
For example:
[widgetid="footer-widget-1"] {
/* CSS for #widget-column-1 here */
}
...or...
#widget-column-1 {
/* CSS for #widget-column-1 here */
}
If you add this to your active theme's style.css it's going to work.
As a side note, you'll probably find CSS Selectors and CSS Combinators useful. Also, in order to become efficient in CSS your code should apply. You'll need two things:
learn to inspect, using developer console of any major browser
learn CSS specificity. This will make you understand fast how strong (specific) your selectors need to be in order for a rule to apply, without breaking anything else.
You might also want to tour the Codex to make sure you understand how WordPress works.
I have lost count of the number of "professional" programmer's websites that are made with wordpress. I have also lost count of how many websites made by freelance developers who use wordpress. So, not exactly a "noob" thing.
As for your code, try running it on page load:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script> <1--
<script>
$(document).ready(function () {
$(".widget-column-1").addClass("footer-widget-1");
$("#widget-column-1").addClass("footer-widget-1");
});
</script>
Developers generally prefer to narrow down their selectors based on specificness, instead of adding !important. But I'll give you the option to use it, if you wish:
And if that doesn't work, I notice that most wordpress developers add:
!important
To the end of every CSS declaration... Basically, this adds priority to your CSS over the template's css.
So, here would be your new code:
.footer {
background: /*stuff here*/ !important;
background-repeat: /*stuff here*/ !important;
background-size: /*stuff here*/ !important;
background-position: /*stuff here*/ !important;
}

How to make CSS "execute" when user is viewing that part of the page?

Similar to how some CSS can be executed by events like using :hover, how could I make the same code execute when the user is simply viewing that part of the page? Example: user scrolls down to footer, and some nice CSS effects execute. I'll add a javascript tag to this thread incase that would be needed.
Edit from comment: Some more context...I have a button with a bunch of CSS effects already in place, and was just looking to "activate" them upon viewing.
CSS is not made for that. You will have to use Javascript.
You could check out this JS library, because it's not possible with CSS.
http://mynameismatthieu.com/WOW/docs.html
You cannot do this in CSS. You will need JavaScript.
If you are using jQuery, it offers a :visible selector. EDIT: jQuery's :visible selector is not the same as "in viewport", as #mplungjan pointed out. #mplungjan also found this page on viewport selectors for jQuery: http://www.appelsiini.net/projects/viewport

Changing CSS Rules using JavaScript or jQuery

Initial Research
I am aware of using .css() to get and set the CSS rules of a particular element. I have seen a website with this CSS:
body, table td, select {
font-family: Arial Unicode MS, Arial, sans-serif;
font-size: small;
}
I never liked Arial Unicode as a font. Well, that was my personal feel. So, I would use Chrome's Style Inspector to edit the Arial Unicode MS to Segoe UI or something which I like. Is there anyway, other than using the following to achieve the same?
Case I
$("body, table td, select").css("font-family", "Segoe UI");
Recursive, performance intensive.
Doesn't work when things are loaded on the fly.
Case II
$('<style>body, table td, select {font-famnily: "Segoe UI";}</style>')
.appendTo("head");
Any other better method than this?
Creates a lot of <style> tags!
Ok, if:
Personal Preference
Then use user styles CSS. According to priority, user styles takes precedence above all other styles. Next comes inline-styles, then !important styles, then specificity, then default browser styles. If it's just for personal preference, pack-up a custom CSS with you and a browser that supports it.
You are the developer
Then don't do this in JavaScript or user scripts. Go down to the problem and change those styles! You are just making the browser work more by actually making it parse stuff you don't want. Since you have access to the code, change the styles instead.
However, since your site could be a public site, style it like genericly for everyone. It's not only you that's viewing the site.
Not the developer:
The best way I can think of (and already did this before*) is to remove external stylesheets from the page and replace them with modded versions of your own liking. That is taking a copy of the original CSS file, change what needs to be changed, and then load it via JS by creating a <link> to that external file, or load the contents via AJAX and put them in a <style>. However, this approach is riddled with obstacles. <link> does not have an onload event so you won't know the external CSS was loaded (there are crafty workarounds though) and AJAXing CSS contents imply that your CSS is in the same domain or the browser and server supports CORS.
Another way you can do it is to have JS peek into loaded stylesheets and modify their contents. This is a more JS intensive work since JS looks for your definition to change in a pile of CSS declarations. This is a safer bet, however, I believe not all browsers can traverse CSS styles or at least do it differently across browsers. Also, if you got a large stylesheet, you'd be parsing it every time.
As you said, .css() would be recursive. True, because it applies inline styles to each affected element. This is good in a sense that inline styles are higher up in the priority so whatever is placed using .css(), you are almost sure that they will take effect. However, it's more work intensive since it involves the DOM now.
* The library I created does not remove existing styles, it just loads and unloads predefined styles declared using it's API
Have a look at:
Quirksmode: Change CSS
Totally Pwn CSS with Javascript
Is the only way to change a style to do it per-element in JavaScript? (possible duplicate)
I'm afraid there is no library for that, I really would like to see one...

How to keep user from seeing "ugly" HTML precursor when using jQuery UI and RequireJs?

I'm trying to adapt a jquery-ui codebase to use RequireJs, and I'm deploying it on a much slower (but scalable) virtualized cloud service than the dedicated host I was using before.
My pages are by default an ugly catastrophe of vanilla HTML. The only thing that brings this mess to life are calls to JavaScript functions, which give it the appropriate tab controls and layout. In fact, the page is laid out long and vertical...one section after another...before I call the .tabs() function which folds them up into a single unit with a horizontal control.
(Fairly confident I'm "doing it right" in the jQuery UI mindset. By not building the whole UI through code to start with, it can be at least looked at with JavaScript disabled. Though I doubt anyone is still using Lynx, there are issues of accessibility...or making sure your content is analyzable by search engines. I'll spare you my old man speech about how this is an absurdist way of achieving content/UI separation. :-/)
When I was using <script> tags to load my 3rd party library dependencies and the $(document).ready to run the jQuery UI voodoo, the user never saw the vanilla ugly HTML. Now that I'm using RequireJs, the page.js file lags and loads asynchronously after the HTML...waiting for libraries that aren't really needed for the DOMready handling. The slower server makes this look really awful.
I could of course use CSS styling to hide the ugliness at the outset, and overlay with a "Loading..." graphic until the UI was ready. That's what came to mind first, and a similar approach is suggested here:
Jquery UI interface looks ugly before document.ready
(Note: It seems like such a common problem that I'd almost think there'd be a RequireJs plugin that went ahead and did this. Is there?)
In any case, I didn't seem to have to worry about this before...and I'm wondering if I'm missing some simpler solution. How do you keep users from seeing "ugly" HTML if you're using RequireJs?
I'm with you that you should do some CSS wizardry and then in RequireJs's "kick it off" script, hide it. You should also consider SEO impact and JavaScript disabled scenarios.
Remember, at the end of the day, it's just HTML, CSS, and JavaScript. What ever templating / code generation system you use to get you there, at the end of the day, it's just HTML content, styled with CSS, and animated with JavaScript.
I'd argue that it makes more sense to use something like node-browserify to do all of your Javascript module requires and then stream down the single JS file to the end-user.
Why go through all of the TCP handshakes and HTTP headers to get the same thing at a much lower performance when the client is obviously not intended to be run in an offline mode?
Hey Doc, it hurts when I do this.
Well, then don't do that!
I'm having the same issue with Jquery Mobile and RequireJS.
I first tried following this tip and hid the "ugly HTML" by adding CSS:
.requireJS-init { visibility: hidden;}
.requireJS-init.done { visibility: visible;}
and assiging .requireJS-init when the page fires up and removing it once everything has been loaded by adding another class done (you could remove the initial class, too I guess).
However this causes two problems:
1. Users might have a blank page for a while depending on your content being loaded
2. IE8 fails, because (in my case) Jquery Mobile tries to focus on elements while they are still hidden.
I tried moving around the class form HTML to BODY to elements holding the page content, but nothing really worked.
A much easier CSS-only solution is this:
.ui-mobile-rendering:before {
width: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: block;
height: 100%;
z-index: 0;
background:#fff url(../images/ajax-loader.gif) no-repeat center center;
content: ""
}
The ui-mobile-rendering class is on the body while JQM does it's widget enhnacements. Once the page is done, the class is removed. By adding a fullscreen :before - in this case with the JQM loader as background image - you hide everything on the page until it's rendered. No need for visibility:hidden, IE8 doesn't complain (thank good, IE8 and FF3.6 know :before).

dynamically load css approaches

I have long known that you can load style rules into a page dynamically by using addRule() and insertRule(), depending on whether it is IE or a standards compliant browser. But I just discovered that on Chrome, a much more generally-useful (for me) approach works just fine: create a style element, add a texnode to it with arbitrary css text (it could be the contents of a css file), then add that to the document. You can also remove it by removing that style node from the document. For instance this function works fine when I send it the string "div {background-color: red; }\n p {font-family: georgia; }":
var applyCss = function (cssString) {
var scriptNode = document.createElement('style');
scriptNode.appendChild(document.createTextNode(cssString));
document.getElementsByTagName('head')[0].appendChild(scriptNode);
return scriptNode;
};
While I understand the benefits of doing it on a rule basis in some scenarios, this shortcut (which is kind of analogous to using innerHTML instead of building elements part by part using DOM techniques) would be particularly useful to me in a lot of situations if I can count on it working.
Is it consistently supported? Is there any downside to this approach? I'm particularly curious because I've never seen this approach suggested anywhere.
The primary reason you wouldn't see this approach mentioned or suggested anywhere is largely because it's unnecessary. Instead of constantly trying to edit style elements, you should have a set of classes that you add and remove from elements dynamically.
In my experience, dynamically adding a style element with text works cross browser. So far I haven't found a browser that doesn't work with something like:
//jQuery for brevity
$('<style>p{margin:0}</style>').appendTo('head');
The only situation I've ever needed this in was for adding a large set of very specific styles for usage with a bookmarklet. Otherwise, I'll dynamically add a stylesheet:
$('<link rel="stylesheet" type="text/css" href="path/to/stylesheet.css />').appendTo('head');
But really, stylesheets should already exist within the HTML.
Use YepNope lib, it will do the dirty stuff for you. And it's only 1.7kb when gzipped and minified.

Categories

Resources