Strange CSS precedence behavior after AJAX load - javascript

I am trying to figure out how I seem to be losing my CSS precedence on an AJAX loaded page. I am loading my custom CSS last on the main page, so that should allow my CSS to override any bootstrap CSS. After loading new content via AJAX, bootstrap is overwriting my custom CSS. I can see via browser debug that bootstrap has overwritten the property.
Custom CSS Styling:
.mytableclass td {
font-size: small;
text-align: center;
vertical-align: middle;}
As bootstrap isn't setting the font-size or text-align, it applies fine, but my vertical-align is overridden. I am not loading the CSS files again in the AJAX loaded page. There has to be some sort of reason, but after several hours I can't figure it out.

As you didn't post the Bootstrap CSS class definition, I'm going to guess it is a CSS selector priority issue.
Is the Bootstrap CSS selector more specific than yours? Then it gets priority over any CSS loaded later. Either make your selector as specific or more specific, or apply the !important directive, but that is not recommended (also see ITCSS).

Loading a specific bit of CSS after everything else does not give it any precedence. What you'll want to do is make sure it has a more specific selector. (You could also use !important, but that a hack and I don't recommend it unless you can't get anything else to work.
If .mytableclass td is the selector bootstrap uses, consider adding something to the front of it. ie body .mytableclass td. Or you can go into the HTML itself and add an id that you only use as a selector in the AJAX CSS.

Related

Editing CSS (changing selectors) at runtime with JavaScript: prevent application inside DIV

I would like to be able to prevent a CSS file from applying to the inside of a DIV tag.
The CSS file is included in the <head> section of a HTML document. I cannot remove the file or change it. All I have control of is the inside of that DIV tag. The HTML document is generated with MediaWiki, so I'm not allowed to use iFrames. I cannot host my content anywhere else, but I can take external resources such as CSS and javascript, upload them, and include them in the inside of my DIV.
Currently, I have Jquery, and I can include all sorts of external libraries.
Using jQuery to find the <link rel="stylesheet" href=...> and then .remove()ing it does work, but that messes up the rest of the page, which I am prevented from doing by a LOT of red tape.
Is there a way to "javascriptically" do something to the stylesheet such that it applies only to anything that's not inside my DIV? Maybe using the :not() selector?
I have no idea, and I have never touched the not selector before. Please help. Thank you.
You can't make prevent CSS from applying to a part of the document, even if you could change it (which is doable with Javascript as long as you don't care about users with no Javascript). You have two options basically:
Override the CSS. Probably the least painful way is to take some CSS reset stylesheet and prefix every rule so that #1 it only applies to your div, #2 it has high enough specificity to override all MediaWiki rules. You can then apply your own styles on top of that.
Make the div not part of the document. You could create an iframe in Javascript and move the contents of the DIV there. (Shadow DOM would be a nicer approach but there is not much browser support yet.)

Style a dynamically created div element

I would like to apply a css style to a element after it's created. The element is created by a plugin, so I can't access the event in which it is created.
This element has the .appointments-address-field class. I have tried to add a simple style:
.appointments-address-field {
background: #fff;
}
... with no success. Then I tried to attach a delegated load event in jQuery:
$(document).on('load', '.appointments-address-field'), function() {
$('.appointments-address-field').css('background', '#fff');
});
... with no success either.
How can I apply a style to that element?
Edit: Sorry, I misspelled my jQuery code. Many of you have suggested to use .css instead of .style, but I did use that.
You were correct in the first place to use CSS and not code, but your css selector must be at least as specific as any existing background style applied to that element. I am of course assuming your styling is already included after the plugin's styling.
Use a tool like Chrome's F12 DOM inspector to view where the styling for an element is coming from and whether that is more specific.
e.g. it may need to be something like:
.some-parent-wrapper .some-appointment .some-group .appointments-address-field {
background: #fff;
}
If you were able to provide a link to the actual site, it would be easy to suggest the correct selector.
Update:
Do not resort to the easy fallback of !important unless the current selector also uses it: http://james.padolsey.com/usability/dont-use-important/
Your first way should work, provided:
You include it in a stylesheet after the stylesheet related to the plugin (if any).
The plugin's stylesheet doesn't use !important; if it does, you can add that to your style.
The plugin doesn't style the background of the element directly; if it does, you can use !important in your stylesheet to win.
The plugin's rule isn't more specific than yours; if it is, make your rule more specific. In any modern browser, you can right-click the element, open the dev tools, and see the rules applied to it.
Fighting style wars with !important isn't ideal. If the plugin is making this difficult in that way, you may be better off finding out what event (if any) is fired when the plugin adds the element, and then running your
$('.appointments-address-field').css('background', '#fff');
...code in response to that. (load is not fired when elements are added to the DOM, which is why that didn't work.) Also note that the function is css, not style.
Please use .css of jQuery
$(document).ready(function() {
$('.appointments-address-field').css({'background':'#fff','border':"#000"});
});
after loading plugin, this line added in your code if u have ready event already included please below code only
$('.appointments-address-field').css({'background':'#fff','border':"#000"});
try
.appointments-address-field {
background: #fff !important;
}
problems can be another style directive put different background

Display div if javascript is enabled. Must have !important

I have a featured slider on my homepage that I had rigged to be completely hidden if javascript is disabled. I had a script that would then display the featured slider if javascript was enabled.
document.write('<style type="text/css">#JQuerySlider1Container{ display: block !important;}</style>');
Apparently that code is not valid according to W3C. (Though it worked so this is a total bummer).
I found an alternative piece of code that I like but I must have !important in order for the slider to be displayed.
document.getElementById('JQuerySlider1Container').style.display='block !important';
But it doesn't work with !important.
Does anybody have a simple solution for this problem?
Its not good practice to add CSS using JS. You should keep HTML, JS and CSS all completely separated.
The way to show/hide things using JS is by default hide the objects you want to hide using CSS, e.g:
#JQuerySlider1Container {display:none;}
The in your JS, add a class to the body, using something like:
$(function() {
$('body').addClass('has-js');
});
Then you can write specific CSS rules knowing that you have JS enabled, e.g:
.has-js #JQuerySlider1Container {display:block;}

TinyMCE: manually loading stylesheets by using link-tag

I'm starting to use TinyMCE in an existing project. Unfortunately the project uses a stylesheet which declares CSS rules for selector #content td, which was a bad decision by the designer. Theses rules are breaking the TinyMCE theme. However, the rules are applied very often in the project. Therefore, replacing them would be too much effort.
The #content td rules have higher priority because they are loaded before TinyMCE loads it's CSS rules from javascript. If I was able to load TinyMCE CSS by using a <link> tag, I could solve the problem by loading the TinyMCE stylesheet before the project's stylesheet.
Is the assumption correct?
Is there a way to manually load tinyMCE stylesheets via link-tag?
Do you have any other ideas?
Loading tinyMCE's styles using a link tag vs. javascript won't solve the problem, because the problem lies in CSS specificity.
The rules of CSS state that the last valid rule with the highest specificity will take precedence.
TinyMCE's table rules are of the form .mceitemtable td, which has a specificity of 0,1,1.
Your #content td rules begin with an ID, which has a specificity of 1,0,1.
Therefore, the ID rules will always win over tinyMCE's class-based rules, regardless of the order they're loaded.
See http://www.stuffandnonsense.co.uk/archives/css_specificity_wars.html for more detail about CSS specificity.
(Aside: I didn't think TinyMCE loaded its CSS via javascript anyway? The default behaviour for tinyMCE is to load the editor in an iframe, and inspecting said iframe shows that frame loads its own CSS via <link> tags.)
You are able to load your own stylesheet in order to overwrite default tinymce css. Have a look at the tinymce setting content_css.

How do I prevent CSS interference in an injected piece of HTML?

I'm currently developing a Safari extension that uses an injected script to further inject some HTML into the current webpage, as well as injecting some other scripts to make it work. This is all working fine, but the issue is that the HTML that is injected gets affected by CSS stylesheets that the webpage has already imported. For example, the HTML looks perfect on Google.com (which has relatively little CSS styling), but awful on StackOverflow.com (which styles buttons etc).
jQuery is injected into the webpage at the time of this HTML being displayed, so I have that available. I've tried all kinds of things, including walking through all of the elements and calling removeClass() on each of them, to no avail. I've also tried to add "CSS reset" classes, etc, but nothing seems to be working.
What's the best way to go around preventing the CSS from interfering with my HTML?
You can't prevent that from happen. However, you can override the CSS rules. Give your main element a unique id (which really should be unique by obfustation, like "yourapplicationname_mainelement_name" or something), then override all possible styles that might give strange effects on your html.
Your plugin:
<div id="yourapplicationname_mainelement_name">
<p>My paragraph that must not be styled</p>
</div>
Your css:
#yourapplicationname_mainelement_name p {
display: block;
color: black;
background: white;
position: relative;
... and so on ...
}
As your css style rules are the most specific, given your id, they will override any settings present on the page where your html is injected.
Further... It might be hard to see what rules are the most important. You can use firebug or similar to understand which is overriding another. You'll have a hard time without it when developing your application.
that's a tough one. two options as I see it.
You could set a wrapping div around all your content and prefix all your css with that. example:
<body>
<div class='wrappingDiv'>
...
</div>
</body>
stylesheet:
.wrappingDiv * {}
Then when you inject jquery use that to close off the initial wrapping div before your content and to wrap any following content in the another wrapping div.
Issues:
Only possible if you are injecting
other site content onto your own
site.
This could get complicated
depending on where you are injecting
html.
The other option is to load a resetting stylesheet that targets your injected html specifically. In this case only your injected html would be wrapped but you'd need a css file that reset all attributes for all tags to their default before you add your own styles. No real issues here, just not very elegant...
Another way would be to use an element that doesn't inherit stylesheet like an iframe, but that comes with its own issues...
i have seen on different plugins that they put the code inside a iframe and they use JS to interact with the rest of the page, so you can not change the css inside.
Also i have seen that when injecting html code,people sets the style of the plugin content using the "style" attribute inside the tags so the browser will give priority to the css inside the style attribute and not the css file. The idea is to override the css,usually with the "!important" clause. But you might have some problems on different browsers
EDIT i forgot to say that my answer is on the case that you inject the code on someone's else page where you cannot control directly the css

Categories