You are here:Home»KB»Web Design»CMS»Joomla»Overriding CSS rules in Joomla content
Saturday, 12 December 2015 13:46

Overriding CSS rules in Joomla content

Written by

Background

This is likely to happen when you are just using an inline class you have declared in the content to change how an image looks. Because Joomla template coders are always more precise with their CSS selectors these will always trump your simple CSS class declaration.

When I was making my 'image styling' page I discovered there were some stylings for K2 that was affecting my image CSS code. I then wrote a jQuery script that would disable the offending CSS file. This however had the effect of removing all of the K2 styling.

I had previously managed to overide the styling from the "jsn_ext_k2.css" by using !important on the rules i had added for my example. This would however add lots of time whenever i wanted to add inline CSS into my articles and I am all about saving time.

The next thing I thought off was to use an 'inline CSS reset' styling block, but I would still have to use !important in this code block to overide the same rules I had just overidden except I will have added another pointless styling level. The key to the reset.css to work is knowing how CSS works and scans through its code. The key point is to use the reset.css to disable the exact rules that are causing the issue, then use your other inline scripts normally. I had to use !important to make sure rules my were applied because a more specific rules for images was being loaded from the "jsn_ext_k2.css", the more precise the rule, the more important it is and therefore will overide any previous rules that were less specific. You can utilise the ibuilt DOM viwer of Firefox to get wheich CSS rules are causing the issue. You should only disable the rules in the reset.css script that are causing you isses, there is not point in making it over complicated. So this didnt work either.

Then it dawned on me, why don't I paste all of the class into the images style="", this worked well. Success!!!

Overview

There are many ways to declare CSS rules and styling but in this article I will be investigating overiding the following offending rules as this can be very useful if you need page specific rules and do not want to hack core code or you template's CSS files.

The Offending Rule

/* Line 553 jsn_ext_k2.css */
div.itemBody img, div.userItemList img, div.catItemBody img, div.tagItemBody img, div.latestItemBody img {
    max-width: 100%;
    border: medium none;
    padding: 0px;
}

In the CSS file

<link rel="stylesheet" href="/templates/jsn_time_pro/ext/k2/jsn_ext_k2.css" type="text/css" />

I discovered a problem when declaring a CSS class in my article that I would then use to re-style some demo images. The rules above would always be applied after my inline delcared class and rules because it is more precise so causes the border and padding not getting applied correctly from my rules.

The inline code in question I want applied to an image.

/* Thin Grey border and shadow */ 
.frame-1 {
    -moz-border-bottom-colors: none;
    -moz-border-left-colors: none;
    -moz-border-right-colors: none;
    -moz-border-top-colors: none;
    background: transparent -moz-linear-gradient(center top , #fafafa, #dddddd) repeat scroll 0 0;
    border-color: #c9cbcd;
    border-image: none;
    border-radius: 0;
    border-style: solid;
    border-width: 1px 1px 2px;
    box-shadow: 0 8px 6px -6px black;
    display: inline-block;
    outline: medium none;
    padding: 4px;
    transition: all 300ms ease-out 0s;
}

How the image first looked when applying the class

cat whiskers kitty tabby 300x200

If you examine the CSS rules applied to this image you will find that the rules from jsn_ext_k2.css are being applied which removes the border and padding

How the image should look

cat whiskers kitty tabby 300x200

For those interested i copied all of the rules frome the .frame-1 class into the style="" of the image, but how I got here is described below.

So now you know the problem What next?

There are different wasy to manipulate CSS rules:

  • Override CSS rules with an inline CSS
  • Override CSS rules with an inline CSS but using !important
  • An inline reset.css (almost the same as above but with a specific purpose)
  • Remove or unset a CSS attribute on the element level with jquery
  • Remove the offending CSS file with javascript
  • Change the css attributes with javascript
  • Remove all attributes on an element and then apply a class - eg  jQuery("div.itemBody img").removeAttr();
  • Put the code directly in the element's style="" instead of using a class declaration. This will always overide any code set anywhere in the CSS (CSS files / Inline) except where an !important has been used and in this case all you have to do is append an !important to the relevant rule that is not working. This method allows the styling to be visible in the WYSIWYG.
  • Add all of the attributes via javascript into the element

Notes:

  • i cannot overide more precise rules when i just have a class in my selector, classess might be rendered lasty
  • you cannot remove CSS rules where they are declared from a CSS file without complicated programming

jQuery - Changing CSS elements

The following code snippets all change their specifed elements to have the specified values. 

<script type="text/javascript">
	jQuery("img").css({
             "border-color":"red", 
             "border-width":"5px", 
             "border-style":"solid",
             "padding":"5px"});
</script>

<script type="text/javascript">
	jQuery("div.itemBody img").css({
             "border-color":"red", 
             "border-width":"5px", 
             "border-style":"solid",
             "padding":"5px"});
</script>

<script type="text/javascript">
	jQuery('div.itemBody img').css({
             'border-color':'red', 
             'border-width':'5px', 
             'border-style':'solid',
             'padding':'5px'});
</script>

<script type="text/javascript">
	jQuery('div.itemBody img, div.userItemList img, div.catItemBody img, div.tagItemBody img, div.latestItemBody img').css({
             'border-color':'red', 
             'border-width':'5px', 
             'border-style':'solid',
             'padding':'5px'});
</script>

Notes

  • Note the different type of selectors which are the same as you would use in CSS including how to seperate them with spaces and commas.
  • " and ' are interchangable.
  • No blank lines inbetween the declarations are allowed
  • The CSS rule attributes are declared by a Key:Value pair
  • Each Key:Value pair are seperated by a comma
  • It does not matter if there are extra spaces between the key:value pairs
  • It does not matter if there are extra spaces in the key or value enclosures
  • This code follows CSS rules including the selector. You can specify different target elements by seperating their selectors by using a comma. these might work,
  • You cannot split the selectors on to different lines (unless they wrap)
  • Javascript acts at the element level, and element levels are the last to be applied
  • The code must be put at the end or enclosed in a run when document is ready
  • You can set different values for attributes at the element level:
    •  A value - the attribute will have whatever you set to it ie 10px/50% etc..
    • "" - this unsets the elements attribute
    • '' - this unsets the elements attribute
    • unset - this unsets this attribute
    • intial - sets the value to the browsers default
    • inherit - this will use whatever the parents value is for this attribute

Javascript must be executed after the specified element is rendered

This is something i always get mixed up with but basically if you want Javascript/Jquery to interact with an element then the script must be run after the element has been rendered. You can do this by:

  • Placing the script after the element to be altered
  • Place the script at the very end of the page
  • Use delaying code such as $( document ).ready() / jQuery ( document ).ready() , this allow you to place the code anywhere and helps keeps things tidy. Read - $( document ).ready() | jQuery Learning Center

Example

This Works !!! - This works because the script is executed after this element has been rendered !!!

	<script type="text/javascript">
		jQuery("p.testclass").css('background-color', 'red');
	</script>

This does not work !!! The element was rendered after the script had been executed so was not altered.

Solutions - What should I Do?

Now that I have got that all out of my head here is the list of the recommended solutions:

  1. Element style - Add all of the styling rules into the elements style="" - This method allows the styling to be visible in the WYSIWYG.
  2. Element stylewith !important - Add all of the styling rules into the elements style="" but with !important where needed - This method allows the styling to be visible in the WYSIWYG.
  3. Inline CSS - A simple inline CSS styling.
  4. Inline CSS with !important - A simple inline CSS styling but with !important where needed.
  5. Complex Selector - A CSS rule that matches the offending CSS rule which the inline version will overide the file based rule.
  6. Complex Selector with !important - A CSS rule that matches the offending CSS rule which the inline version will overide the file based rule but with !important where needed.

I have not sorted them in to a prefered order of use yet, but from 1- 6 they get harder to configure.

Links

Read 1216 times Last modified on Tuesday, 05 January 2016 22:38