22

My website has currently 3 CSS files that are automatically included as a part of the website and I do not have access to the source i.e. index.html of the website but I do have access to the CSS files of my website.

I am trying to use my own style to override my websites CSS files and create a new CSS file that would contain all the styling that I would like to overwrite on my website.

I have tried using @import url(css4.css) and I have placed that at the top of my last CSS file but that wouldn't overwrite the last CSS file's styling.

How can I achieve this?

<link rel="stylesheet" type="text/css" href="currentCSS1.css">
<link rel="stylesheet" type="text/css" href="currentCSS2.css">
<link rel="stylesheet" type="text/css" href="currentCSS3.css">   
<!-- How to add this below just by using CSS? -->
<link rel="stylesheet" type="text/css" href="newCSS4.css"> 
dippas
  • 58,591
  • 15
  • 114
  • 126
Neophile
  • 5,660
  • 14
  • 61
  • 107
  • u can use !important at every line of ur css, but, erm, u have to get access to index.html and just remove unnecessary csses from header) – Legendary Mar 23 '15 at 09:32
  • Why don't you just delete all of the content of css3 and replace it with @import url(css4.css), then copy the contents of the old css3 to css4, and override the rules here? – Balázs Varga Mar 23 '15 at 09:32
  • I can't change the css3 because its something that the developers of the website keep updating which is why I don't want to delete anything that is already available because with future updates for that website, I would like to make sure my changes are in a seperate file rather than on one of the source files as it may get overwritten during upgrades. – Neophile Mar 23 '15 at 09:36
  • 1
    Your @import change would get removed in that case anyways if they were updated. What other files do you have access to? – ilia Mar 23 '15 at 09:37
  • Yes my import would get removed which is why I'm looking for a bullet-proof solution. – Neophile Mar 23 '15 at 09:38
  • You need to make your selectors more specific than those currently used. eg. `.some-item` becomes `body .some-item` – Turnip Mar 23 '15 at 09:39
  • 1
    I thought @import was only supposed to be kept at the top (even before any comments) rather than the bottom? – Neophile Mar 23 '15 at 09:39
  • 6
    I don't know where you people are getting the idea that @import can be included anywhere but the top! https://developer.mozilla.org/en-US/docs/Web/CSS/@import Stop upvoting incorrect comments – ilia Mar 23 '15 at 09:42
  • 1
    Exactly, I was looking for that link to support my statement. Thanks @ilia – Neophile Mar 23 '15 at 09:43
  • Can you not remove the CSS file by file name/URL and then add yours via JS? – lshettyl Mar 23 '15 at 10:09
  • I don't want to play with the source file/files already present because of future updates to the website. Not intending to use JS because there are tons of pages where the css is being loaded. – Neophile Mar 23 '15 at 10:10
  • 2
    you can not override styles by placing your css file as the latest style element. You should override by changing your selectors in the your css file. for example if there is rule like "div { bacground-color: red; }" and want to change background color to green use "body div { background-color: green;}" check: https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity – yavuzkavus Mar 23 '15 at 10:23
  • You essentially want to change part of the DOM (either removing a previous `link` or adding a new `link`). Unfortunately, you cannot achieve DOM manipulation with CSS (that's what javascript lives for). I would look into http://stackoverflow.com/questions/1598899/unload-css-from-webpage to unload the previous CSS link and then create a JS file to load in your new CSS. – Michael Mar 25 '15 at 17:59
  • 1
    Is this only for your eyes? Many browsers (Firefox and Safari I am certain) allow you to load custom stylesheets. You set the custom stylesheet from the browser options and it's as if it's the last stylesheet for every website you visit. – Joseph Hansen Mar 25 '15 at 18:10
  • I am trying to understand the question a little better. Please tell me if you have access to the webserver at all or is the new stylesheet just something for your eyes only and to be tested in your workstation only. – Sai Mar 25 '15 at 21:32
  • @yavuzkavus, that is not correct. If two rules have equal specificity, the later one wins. Moreover, adding 'body' to the rule to override an earlier rule is bad practice - it is not repeatable and not self-documenting. – radiaph Mar 26 '15 at 14:13
  • Yes I do have access to the webserver but not the index.html. I have access to the css and js files but I would prefer to do it using the css files. – Neophile Mar 26 '15 at 14:13
  • @TheNewbie, are these statements correct? 1) You cannot modify the HTML of the page at all, and therefore cannot include another CSS file. 2) You can modify the CSS files, but the developers may modify them again later and remove any changes you made. Hence you cannot permanently modify the CSS files. 3) You cannot/do not want to use Javascript (despite tagging the question with Javascript and JQuery). If all of these things are true, there is no solution to your problem. – radiaph Mar 26 '15 at 14:29
  • Yes the above statements are correct and I possibly might have found a solution myself. If I get it working properly, I would post the solution below. – Neophile Mar 26 '15 at 14:33
  • @phari, you are right, if two selectors are same, the last one overrides. I dont know whether selectors in the css files The Newbie mentioned are same or not. – yavuzkavus Mar 26 '15 at 22:30
  • The selectors are the same and I have made some selectors even more specific just to make sure I'm just targeting the ones I need. So all that is good. – Neophile Mar 27 '15 at 10:11
  • Check out this link: http://www.cssreset.com/scripts/eric-meyer-reset-css/ which is a great starting point to reset any css rules you might want to get rid of. For more details, visit this other link: http://meyerweb.com/eric/tools/css/reset/ – RobertoNovelo Mar 31 '15 at 20:12
  • @TheNewbie, do you need this solution for just one personal page, or several pages? Also, can you add more files to the server? if so, what language is the server running? PHP for example? I have ideas in mind. – Drakes Apr 01 '15 at 03:52
  • There are several pages affected by the three stylesheets I mentioned. I can add more files on to the server. – Neophile Apr 01 '15 at 08:20

12 Answers12

51

Besides using !important that most answers are advising you to use, this is a matter of CSS specificity

The concept

Specificity is the means by which a browser decides which property values are the most relevant to an element and gets to be applied. Specificity is only based on the matching rules which are composed of selectors of different sorts.

How is it calculated?

The specificity is calculated on the concatenation of the count of each selectors type. It is a weight that is applied to the corresponding matching expression.

In case of specificity equality, the latest declaration found in the CSS is applied to the element.

Some rules of thumb

  • Never use !important on site-wide css.
  • Only use !important on page-specific css that overrides site-wide or foreign css (from ExtJs or YUI for example).
  • Never use !important when you're writing a plugin/mashup.
  • Always look for a way to use specificity before even considering !important

can be represented by 4 columns of priority:

inline = 1|0|0|0

id = 0|1|0|0

class = 0|0|1|0

element = 0|0|0|1

Left to right, the highest number takes priority.


Here is a snippet with a Full example of a CSS specificity

/*demo purposes*/
body {margin: 0;padding: 0}
div,article {min-height: 200px;height: 100%;width: 100%}

/*CSS Specificity */

/* SPECIFICITY: 0/1/0/0 */
#id {
  background-color: green
}

/* SPECIFICITY: 0/0/1/0 */
.class {
  background-color: yellow 
}

/* SPECIFICITY: 0/0/0/1 */
section {
  background-color: blue 
}
  
/* ------------ override inline styles ----------- */

/*to override inline styles we  now use !important */

/* SPECIFICITY  0/0/1/0 */

.inline {
  background-color: purple !IMPORTANT /*going to be purple - final result */ 
}
<article>
  <div id="id">
    <div class="class">
      <section>
        <div class="inline" style="background-color:red">
          <!--SPECIFICITY 1/0/0/0 - overridden by "!important -->
        </div>
      </section>
    </div>
  </div>
</article>


Now here is the Full snippet step by step

ID: GREEN

/*demo purposes*/
body {margin: 0;padding: 0}
div,article {min-height: 200px;height: 100%;width: 100%}

/*CSS Specificity */

/* SPECIFICITY 0/1/0/0 */
#id {
  background-color: green
}
   
<article>
  <div id="id">
    <div class="class">
      <section>
        <div>             
        </div>
      </section>
    </div>
  </div>
</article>

CLASS: YELLOW

/*demo purposes*/
body {margin: 0;padding: 0}
div,article {min-height: 200px;height: 100%;width: 100%}

/*CSS Specificity */

/* SPECIFICITY  0/0/1/0 */
.class {
  background-color: yellow
}
<article>
  <div id="id">
    <div class="class">
      <section>
        <div>
        </div>
      </section>
    </div>
  </div>
</article>

ELEMENT: BLUE

/*demo purposes*/
body {margin: 0;padding: 0}
div,article {min-height: 200px;height: 100%;width: 100%}

/*CSS Specificity */

/* SPECIFICITY  0/0/0/1 */
section {
  background-color: blue
}
<article>
  <div id="id">
    <div class="class">
      <section>
        <div>
        </div>
      </section>
    </div>
  </div>
</article>

INLINE STYLE: RED

/*demo purposes*/
body {margin: 0;padding: 0}
div,article {min-height: 200px;height: 100%;width: 100%}

 
<article>
  <div id="id">
    <div class="class">
      <section>
        <div style="background-color:red">
        <!--SPECIFICITY 1/0/0/0 -->
        </div>
      </section>
    </div>
  </div>
</article>


OVERRIDDEN INLINE STYLE: PURPLE

/*demo purposes*/
body {margin: 0;padding: 0}
div,article {min-height: 200px;height: 100%;width: 100%}
/*CSS Specificity */

/* SPECIFICITY  1/0/0/1 */

section > div {
  background-color: purple !IMPORTANT
}

 
<article>
  <div id="id">
    <div class="class">
      <section>
        <div style="background-color:red">
        <!--SPECIFICITY 1/0/0/0 -->
        </div>
      </section>
    </div>
  </div>
</article>

You can calculate the specificity of your element(s) here


Note:

A must read on this subject

dippas
  • 58,591
  • 15
  • 114
  • 126
7

Here's a fun solution no one has mentioned.

Facts:

  1. You cannot modify the HTML of the page at all - no problem!

  2. You can modify the CSS files, but the developers may modify them again later and remove any changes you made - not a worry.

  3. You cannot/do not want to use Javascript and JQuery - fine by me.

  4. You can add more files on to the server - Excellent!

Let's do some .htacess hacking for fun and profit!

Document root .htaccess file:

Options +FollowSymlinks
RewriteEngine on
RewriteBase /

RewriteRule ^(.*?)css3.css(.*?) $1hackedCSS3.php$2 [L]

Result: hackedCSS3.php is silently served instead of css3.css on every request.

REF: http://httpd.apache.org/docs/2.2/howto/htaccess.html

hackedCSS3.php file:

<?php

// Send the right header information!
header("Content-type: text/css; charset: UTF-8");

// Output the css3.css file
echo file_get_contents("css3.css");
?>

// Add your CSS here with any neat !important or override tricks (read: specificity)
div { ... }

Bonus:

You could expand this solution to include all three .css files in this one .php file (but only serve, say, css3.css and send the css1.css and css2.css to a black hole with .htaccess), and use clever regular expressions to remove/modify those developer's CSS without touching any of their files. The possibilities are tantalizing.

Addendum:

Can you be a bit more specific on where to include these files?

The .htaccess file should be in the document root directory of the website. This is where www.example.com/index.html would load index.html

Should the hackedCSS3.php file be in the same directory as the other css files?

It can be in any directory you specify in the .htaccess file. The document root is fine. Change

RewriteRule ^(.*?)css3.css(.*?) $1hackedCSS3.php$2 [L]

to

RewriteRule ^(.*?)css3.css(.*?) /folders/you/want/hackedCSS3.php$2 [L]

Should our css content (where you specified // Add your CSS here...) should be within html style tags?

No. Treat your CSS code in that section as if it were a .css file. You do not need <style> tags.

Drakes
  • 23,254
  • 3
  • 51
  • 94
  • Where do I find this .htaccess file please? – Neophile Apr 01 '15 at 10:14
  • Just create it with a text editor. Name it ".htaccess" and drop it in the root of your server. Notice the leading dot. Here is a handy doc: http://www.javascriptkit.com/howto/htaccess.shtml – Drakes Apr 01 '15 at 10:15
  • @TheNewbie Hi, any luck with this solution? I can hep you with more questions about this – Drakes Apr 01 '15 at 13:00
  • I'm on the case and I'm trying. Will post an update if I get it to work. – Neophile Apr 01 '15 at 15:26
  • I have few questions; 1. Can I do the same thing from the virtualhost file. I already have RewriteEngine on 2. Can you be a bit more specific on where to include these files. I figured that the .htaccess file should be in the root directory of the website, Is that the ROOT folder or the root of the website? 3. Should the hackedCSS3.php file be in the same directory as the other css files? css1, 2 and 3 are in separate directories at the moment 4. Should our css content (where you specified // Add your CSS here...) should be within html style tags? – Neophile Apr 01 '15 at 16:25
  • @TheNewbie Hi, I've answered your excellent questions in my answer. As for vhosts, you can enable rewrite there or in the .htaccess file. It's fine to leave it in .htaccess. This is usually enabled by default. Also, replace `RewriteRule ^(.*?)css3.css(.*?) $1hackedCSS3.php$2 [L]` with `RewriteRule ^(.*?)css3.css(.*?) /hackedCSS3.php$2 [L]` if you want the hackedCSS.php in the document root – Drakes Apr 01 '15 at 16:39
  • "Let's do some .htacess hacking for fun and profit!" Upvote for good sense of humor and original answer. – gfullam Apr 01 '15 at 17:48
  • Still can't get it to work. Been following your steps as mentioned. – Neophile Apr 02 '15 at 08:11
  • To test if your setup is correct, navigate to your http:// ... /css3.css. At least the hackedCSS3.php should display in your browser. Can you confirm this? – Drakes Apr 02 '15 at 09:12
  • If you are having trouble, would you mind sharing one of the css urls? Let's verify that it is being rendered as the php file – Drakes Apr 03 '15 at 04:17
  • How'd that work out? I still want to help you with this – Drakes Apr 15 '15 at 12:39
  • I found that unfortunately PHP wasn't installed on our server and I couldn't get it to install on Apache, been trying a few sources but no luck so far. The server has been installed as java. Would you be having a similar solution along those lines or give me some pointers on installing PHP? – Neophile Apr 23 '15 at 09:23
6

To use CSS only, the best way would to use Chrome or FireFox's developer tools and find the various style you want to overwrite.

The for each of the style you find that need adjusting then use the !important modifier.

.newClass {
  color:red !important;
}

Another way would be to write unique css class names and again use !important if you need. The real trick here is in specificity. If an identifier is more specific the rule will be applied.

6.4.1 Cascading order

6.4.1.4 Finally, sort by order specified: if two declarations have the same weight, origin and specificity, the latter specified wins. Declarations in imported style sheets are considered to be before any declarations in the style sheet itself.

<a class="my-most-awesome-link its-really-cool">Most awesome link</a>

.my-most-awesome-link.its-really-cool {
  text-decoration:none !important;
  color:red !important;
}

If you are desperate you could use javascript to remove the unwanted css.

See this JSBin for a working example.

I found this interesting technique

<script>
function removejscssfile(filename, filetype){
    var targetelement=(filetype=="js")? "script" : (filetype=="css")? "link" : "none"; //determine element type to create nodelist from
    var targetattr=(filetype=="js")? "src" : (filetype=="css")? "href" : "none"; //determine corresponding attribute to test for
    var allsuspects=document.getElementsByTagName(targetelement);
    for (var i=allsuspects.length; i>=0; i--){ //search backwards within nodelist for matching elements to remove
      if (allsuspects[i] && allsuspects[i].getAttribute(targetattr)!=null && allsuspects[i].getAttribute(targetattr).indexOf(filename)!=-1){
          allsuspects[i].parentNode.removeChild(allsuspects[i]); //remove element by calling parentNode.removeChild()
      }
    }
}

removejscssfile("css1.css", "css") ;
removejscssfile("css2.css", "css") ;
removejscssfile("css3.css", "css") ;
</script>
whoacowboy
  • 6,982
  • 6
  • 44
  • 78
3

In your new CSS file, add !important to the block of code, for instance:

if you have this on css1.css:

 h2{
 color:#000;
 }

In css4.css put the same element, but with !important, as follows;

 h2{
 color:#ccc !important;
 }

Therefor, !important will force that this style will be by all means the style set for the element to which it's applied.

Herland Cid
  • 574
  • 1
  • 6
  • 23
  • Please read my question again. That's not what I asked. I asked how can I get this new css file as my last css file without having any access to the source code of the website and just use css to do that. – Neophile Mar 26 '15 at 12:04
  • This is as close to a correct answer as this question is ever going to get. It is not possible to inject a new CSS file as the last one purely by modifying other CSS files, but adding !important as described here **has the same effect**. – radiaph Mar 26 '15 at 14:39
3

Use @import url('css4.css') in one of your existing css page. Then use specificity to be highlighted your new code as bellow:

Html :

<ul class='ulclass'>
 <li class='liclass'>
  <a class='aclass>The text</a>
 </li>
</ul>

css1.css :

.aclass{
   color : red;
}

css4.css :

ul.ulclass li.liclass a.aclass{
   color: green;
}

Then you will have green color in your a element

Eranda
  • 868
  • 1
  • 10
  • 27
2

write a new css, and use id of elements rather than class. Also use !important in css.

Shariq Ansari
  • 3,941
  • 1
  • 27
  • 30
2

An alternative: Rely on the cascade, instead of specificity

A number of solutions here recommend using @import to include your css4.css file and then modifying the selectors therein to have a greater specificity or to use the !important declaration, but there is yet another way.

Paste the entire contents of css4.css at the end of css3.css. In this way, you need not rely on !important or specificity, because the cascading inheritance will adopt your rules at the end of the file if they are of equal specificity.

With this method, you are sacrificing modularity for easier implementation.

Example of pasting, relying on cascade:

/* Contents of css3.css */
.mycooldiv {
    font: bold 1.2em sans-serif;
    color: tomato;
}

/* Pasted contents of css4.css */
.mycooldiv {
    color: lime;
}
<div class="mycooldiv">Hello World</div>

However, it would be easy enough to create greater specificity by simply prepending html to the beginning of every rule in css4.css, if you don't want to paste it at the end of css3.css. This is preferred to adding !important where it works.

Example of importing, relying on greater specificity:

/* @import of css4.css with greater specificity */
html .mycooldiv {
    color: lime;
}

/* Contents of css3.css */
.mycooldiv {
    font: bold 1.2em sans-serif;
    color: tomato;
}
<div class="mycooldiv">Hello World</div>
gfullam
  • 11,531
  • 5
  • 50
  • 64
1

I think I have an answer. The way that I have tried to achieve this is:

1) Say my css3 is the last CSS in the list and I have all my changes in css4. I have made a copy of css3 and called it "css3-Original.css" and added my css4 in the same folder. I then created another css file called "css3.css" (because that is the last one it takes from the list) and added imports of my Original css3 first and then my overriding css4.css file as given below:

css3.css (The new one)

@import url("css3-Original.css")
@import url("css4.css")

This is the best way I found it to work. This way although I know that my css3.css file will change on updates but I know how I can replace it very easily and quickly. I have used !important in my css4.css wherever necessary (if required) but basically because its the last css file, it uses that styling as compared to any previous ones (unless they are !important).

Thanks for the suggestions guys. I finally managed to come to a solution.

Neophile
  • 5,660
  • 14
  • 61
  • 107
0

If I understand you're question correctly, adding @import url(css4.css) to the top of css3.css does import your stylesheet into css3.css. But your styles are being overridden by the styles in css3.css. This is because of Cascading Order and Specificity. In order for your css4.css styles to be used, your selectors must have a higher specificity than the selector in css.3.css you are trying to override.

Example: <h1> tags will be colored red.

body h1 { //this is more specific
   color: blue;
}

h1 { //this is less specific
   color: red;
}

But since you're @import url(css4.css) line of code will get removed every time the developers update the css3.css file this is not a "bullet-proof solution"

Do you have the ability to add any javascript to the site? If so you could use the following solution

jQuery

$('head').append('<link rel="stylesheet" type="text/css" href="css4.css">');

Javascript

var head = document.head
  , link = document.createElement('link')

link.type = 'text/css'
link.rel = 'stylesheet'
link.href = 'css4.css'

head.appendChild(link)

Source: https://stackoverflow.com/a/11833777/2687861

Community
  • 1
  • 1
Craig Harshbarger
  • 1,863
  • 3
  • 18
  • 29
  • Don't really want to use any javascript because there are tons of pages that I'd have to modify in order to get this to work properly. I'd prefer to get this done just by using CSS. – Neophile Mar 26 '15 at 12:26
  • If there was a single js file included on all the pages it wouldn't be that difficult. There isn't a solution in css with the perimeters you've given. Perhaps if you gave more detail into your specific situation we could come up with a solution. – Craig Harshbarger Mar 30 '15 at 13:53
  • Unfortunately not. I have checked almost all the pages and the js files vary on each. The only files that are common are the css files. – Neophile Apr 01 '15 at 08:23
  • Then I'm afraid that your only option is to use `@import` and re-add it back in every time the developers update the css3.css file – Craig Harshbarger Apr 01 '15 at 16:27
0

Unfortunately, I have to agree with phari.

Quote:

1) You cannot modify the HTML of the page at all, and therefore cannot include another CSS file. 2) You can modify the CSS files, but the developers may modify them again later and remove any changes you made. Hence you cannot permanently modify the CSS files. 3) You cannot/do not want to use Javascript and JQuery). If all of these things are true, there is no solution to your problem.

Commented by phari on Mar 26 at 14:29

Let me break it down. I will try my best to explain why there's no solution (correct me if I am wrong at any of these options);

Option1: Using jQuery or Javascript.
You cannot modify the HTML of the page at all!! You do not want to use jquery nor javascript. This means that all answers to your question mentioned on this page which involves jquery or javascript are disregarded. This does not mean the answers given on this page are wrong. In your case it's not possible.

Option2: @import url(css4.css); Your website has 3 css files that are automatically included as a part of the website, but unfortunately, you DO NOT have access to ANY of these css files. You can not place this piece of code in css3.css, or any of these files. You can modify the CSS files, but the developers may modify them again later and remove any changes you made, which means @import url(css4.css); can also be removed. Also using @import url(css4.css); would be completely useless. You'll have to place @import url(css4.css); at the end of css3.css, but this won't work because @import rules must always be first in a document. If I am not mistaking ilia (who commented on Mar 23 at 9:42) meant the code can be place anywhere in the file. @import url(css4.css); must be at the top. The link ilia provided as "prove" also specify that it's a requirement to place it at the beginning.. Check the two links below. More Info visit http://webdesign.about.com/cs/css/qt/tipcssatimport.htm or https://developer.mozilla.org/en/docs/Web/CSS/@import#Specifications. Option 2 is disregarded too.

I don't think there could be another way to do what you want to do. Hence, there is no solution to your problem.

0

For duplicate CSS definitions, the last definition will have precedence.

If the added css4.css file is actually referenced after the "3 css files that are automatically included", then the css4.css file's definitions should override the prior duplicate definitions from these other files.

If you are not seeing the results that you expect, use the "view source" option of your browser to confirm the sequence in which the CSS files are referenced. Also use the "Developer tools" of the Chrome browser or the "Firebug" add-on for the Firefox browser to find out how the browser is interpreting the CSS definitions to yield a result that you did not expect. These tools should provide insight to your problem.

JohnH
  • 1,920
  • 4
  • 25
  • 32
-2

You can just overwrite the text in the css file available to you, the style which you want from previous css file you can copy that code in the you can add with that new code refresh your website the result you need appears