Is it bad to use !important in a CSS property? - html

I don't know much about CSS (I'm purely a Java/J2EE developer), but I somehow got stuck with a CSS puzzle which I am unable to solve.
I was using a form with a jQuery light box effect which has a div with an id and a class:
<div id="contact-container"
class="myclass"
style="z-index: 1002; height: 386px; width: 450px; position: fixed; left: 406.5px; top: 15%; ">
In my CSS file, I'm using the following entry:
#contact-container {
font: 16px/22px 'Trebuchet MS', Verdana, Arial;
text-align:left;
width:450px;
}
But when this form was displayed as jQuery pop-up, it was getting displayed properly in Mozilla, but on Google Chrome and IE the box was not coming properly: only part of it was being displayed, and was hidden with a scroll bar.
When I saw it through firebug (my first time using it :)), it's showing me something like:
<div id="contact-container"
class="myclass"
style="position: fixed; z-index: 1002; height: 67px; width: 450px; left: 406.5px; top: 15%;">
and for the same settings, it was not coming properly for IE and Mozilla. After lots of Googling, I made the following changes to my CSS:
#contact-container {
font: 16px/22px 'Trebuchet MS', Verdana, Arial;
text-align:left;
width:450px;
height:380px !important;
}
I fixed the height using height:380px !important;, but not knowing much about CSS, I am not sure if this was the right approach, as I searched about height but it was not defined anywhere.
Please suggest if I have adopted a wrong approach.

!important is a useful tool, but the drawback is that it's kind of a tool of last resort. So you don't want to over-use it as you'll end up causing headaches down the road for anyone that's maintaining the site.
However, your example is a typical use. What is happening is that the JS is injecting inline style attributes on the fly. As such, that's over-riding the cascade in your CSS. !important allows you to over-ride that.

!important is valid CSS syntax and there is nothing wrong with using it—provided you understand what it is doing and why it is solving your problem, so that you use it in the right way.
CSS stands for Cascading Style Sheets. You can load multiple styles that layer on top of each other for the same selectors, both with a single CSS file and across multiple CSS files. The later rules within a CSS file take precedence over earlier ones, and rules in a later CSS file take precedence over rules in earlier files. That's the cascade.
You can think of !important as moving a particular rule into a special layer that sits above the others—still is subject to the cascade, but it will only be overridden by subsequent rules that are also marked !important. This enables you to place rules that you want to take precedence earlier in the cascade where this is logical. The most obvious example is to ensure that a rule in a hard-coded stylesheet still will take precedence over a rule that is dynamically-inserted by javascript at load-time... and that's exactly what you're doing here. Appropriate use.
There may, of course, be another way to solve your problem—such as using a more specific selector to target the attribute. There are cases however where changing the selectors available to you are not sufficiently specific to enable this, and where changing the html being generated to add additional selectors may be excessive (e.g. it is markup being dynamically generated by a content management system that does not allow easy customization of that part of the html). In such cases, using !important may be a much more expedient, pragmatic, and in that case be much easier to maintain than the alternative.

In my opinion, it is DEFINITELY bad practice.
Maintaining a site that has !important scattered throughout is a nightmare. If you feel like you need to use !important, what that says to me is that you need to brush up on your CSS specificity.
They're called Cascading for a reason :)

Use !important for development to quickly identify a problem in the cascade, but then fix the problem. It's best to use the least amount of specificity in CSS rules to get something to work. By all means, remove !imporant rule problems before going to production.

If you use !important, it has the highest priority on the element. But take care, if you use twice for a same function (like background-color, or color) on the same element , then the last one will be the highest. Be aware to using twice the !important (means don't do this):
<div id="contact-container" class="myclass" style="z-index: 1002; height: 386px; width: 450px; position: fixed; left: 406.5px; top: 15%; ">
#contact-container {width:450px !important;}
.myclass {width:500px !important;}
In this case, your solution is perfect and absolutely enough.

Related

CSS class is ignored upon hosting

Hi I have a CSS file that holds all my css code for ten or so pages.
I am having issues with CSS classes being ignored.
I have p tags in the body that belong to their own class.
When testing on my local machine they work good and follow their own classes CSS.
However once I upload the site to my host the p tag's class is ignored and it follows the body's CSS.
Can someone please show me what I'm missing.
(Note I tested in Chrome and Safari)
HTML for p tag:
<p class="tinyText">Sample text here</p>
CSS:
body {
background: black;
font-family: Papyrus;
font-size:20px;
color:white;
}
.tinyText{
font-family: Times New Roman, Times, serif;
font-size:20px;
}
EDIT:
On hosted version, inspected element and followed CSS path. It is reading an old version of the CSS file. But the hosted version is the most updated, I double checked. I tried clearing cache and other data but its still getting that old version. How can I force it to get the new version?
CSS Specificity is the answer (as to why your style is being overridden). An ID in the selector adds a higher specificity than your two-class style.
You need to either be more specific on your style (maybe add more classes or add more root elements to increase its value) or (as you mentioned) create an ID that would out-weigh the current stylesheet.
You can also use !important, but many would argue that as hack-ish considering it's primary intent is for client-side customizations (for accessibility).
You should add more css to the p element and see if it gets applied as now only there are two properties, one is font-size which is same as body and other is font-family which you have set to Times New Roman, Times, serif. If these font is not available than it will take body font as fallback.
.tinyText{
font-family: Times New Roman, Times, serif;
font-size:30px;
color: red;
text-align: center;
/*add more css rules here*/
}
Also do a hard refresh or open in incognito mode and do inspect element and see what all elements are coming and what rules are applied.
Also make sure css is called properly in header.
Also avoid using !important and use of ID.
Thanks
first thing you want to do is Create or use a CSS Reset sheet. here is a popular one.
http://meyerweb.com/eric/tools/css/reset/
and add this to the top of your css file.
Some browsers have their own settings for CSS so you always want to take this into account. Now what you want to do is always use inspect element and see if you can see any styles or CSS properties being applied to it. Also use codepen.io this is a great website to link people to your issues and also use to see what things will look like
try avoiding capital in class Name .. jus keep it as tinytext.. at css and class declaration in html

Backslash in CSS padding shorthand declaration

The website Qq.com has a rule-set with two padding declarations which seem a bit strange. My question is, what does the 11px\0 part do? Does this have something to do with overriding the first padding declaration? I understand the use of the slash in situations like these: / (forward slash) in css style declarations, but I have never seen something like this.
.suggestion .s_title {
padding: 3px 0 1px 11px;
padding: 4px 0 1px 11px\0;
color: #a0a3a8;
font-size: 12px;
line-height: 18px;
}
"Backslash zero" is a css hack targeting IE8 for the current rule. This can be a terrible thing to do, unless there is no other choices. What happens is that IE8 will erroneously believe that this is a valid rule to be applied while other browsers won't, leaving you with a chaos rule:
.my-dirty-rule-for-ie-8-only { margin-bottom: 5px\0; }
For this ruleset, that means the second padding will take effect by overriding the first one only if the user displays your page with IE8.
From a developper point of view, css hacks should be avoided at all cost. You seriously never want to deal with rules targeting a specific browser, as it will haunt you forever from the moment you fall for it.
As Harry pointed out, it was a IE specific hack. You use the \0 part to specify the declaration for a specific IE version. More information about it here:
http://codemug.com/html/css-hacks-for-ie6ie7ie8ie9-and-ie10/
And here
http://mynthon.net/howto/-/webdev/CSS-big-list-of-css-hacks.txt
(See: 24. IE9 hack)

what is the purpose of having duplicate styles in css?

i have seen some people in css write something like
.together
{
display:inline;
display:inline-block;
}
not just restricted to display style, but say background-size or background-image for an example
what is the purpose of this? i mean the second one is going to override the first one, so why bother?
Usually this type of behavior indicates a browser hack for compatibility. When browsers detect a property or value they do not know, they ignore it. Thus, if you place the most widely-accepted properties first, browsers will "fall back" to that behavior if none of the latter properties are compatible.
There's a possibility that it's written that way for browser-compatibility. They probably want the element to have a display value of inline-block, but not all browsers support it on all elements. Sitepoint has a good reference for compatibility of the display property.
The background property is a shorthand for all of the background-related properties, so it's common to set background on one selector and then only overwrite specific background properties later on other selectors. And again, you might have multiple background declarations for browser compatibility.
Lets take the following example.
<html>
<head>
<style>
.carlist
{
background-color: red;
height: 30px;
margin: 10px;
margin: 20px;
}
</style>
</head>
<body onload="loadCars()">
Check div style.
<div id="mydiv" class="carlist"></div>
</body>
</html>
In the above example we have 2 margins declared. I checked and found that the 2nd declaration is accepted by browser(FF,IE,Chrome). So I think if we use this for browser compatibility then the most browser specific style should be declared at last. But there are other ways to define browser specific styles. So its better to have single attribute defined.

Cross-browser display

I am testing a web site on Chrome, Firefox and Internet Explorer using the following in a CSS file.
#foot_links1, #foot_links2, #foot_links3 {
position: absolute;
margin-top: 55px;
margin-top: 14em;
color: #02102f;
font-family: Arial;
}
#foot_links1 {
left: 335px;
}
#foot_links2 {
left: 630px;
}
#foot_links3 {
left: 830px;
}
The foot_links1, foot_links2 and foot_links3 all are in one straight line, but the placement of the foot_links1, foot_links2, foot_links3 placement varies with the browser.
How can I correct this?
I suggest using a reset stylesheet.
A reset stylesheet will reduce browser inconsistencies like default line heights, margins and font sizes of headings.
You may also want to check the following articles for further reading:
CSS Tip #1: Resetting Your Styles with CSS Reset
Mayerweb: Reset Reasoning
Stack Overflow: Is it ok to use a css reset stylesheet?
Stack Overflow: Best css reset
Ensure you have this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
This will change the Internet Explorer behaviour boxing model in Internet Explorer 7 or earlier
Ensure that the first rule of all is:
body *{
padding:0;
margin:0;
}
(Maybe it is not a good idea to append this after you already written all the CSS, instead you could use a more specific rute that aims the place.)
Start by ensuring you're running a proper doctype, and check whether the site validates at http://validator.w3.org/
A proper doctype would be xhtml transitional or html 4 strict (html 4 transitional usually makes IE do things differently)
As for reset stylesheets - yes they can be useful, however I try to avoid them, since you're pushing more kbs to your users (longer load times, especially if your webhotel isn't zipping css), and furthermore you're slowing down the browsers rendering, because there are more css rules it has to process.
Finally it just seems hackish to me - I mean you can make it look right without resorting to resetting all sorts of stuff, so why do it ?
You did not say how the placement varies.
I made a quick test with IE8 and Opera and there were some difference in vertical placement.
I fixed that by adding the top property (and removed the 2nd margin-top). For example:
margin-top: 1em;
top: 55px;
But generally, it is not good idea to try and force a specific look. Web page is not printed media.
The users have different preferences, different display devices and they do not all have the same fonts etc. installed.
Although what other people have suggested are all good advice, as a direct answer to your question, use "padding-top" instead of "margin-top" and ensure your divs have a height set. That should get you quite close, or all the way there.

Hide something with CSS without display:none or JavaScript

How can I hide the div without using display:none or JavaScript?
In my country, a lot of Blackberrys come with the CSS support disabled (the mobile companies here are not so good to developers). I have text that says
<div class="BBwarn">
please activate your css support and a link
</div>
I want to hide that once the user activates CSS support, but i can't use display:none; because it is only supported in BB firmware 4.6. It is a public site and I can't make all my visitors upgrade.
Does anybody knows a solution to this? I hope the question is easier to understand now.
Update:
Thank you all for the answers but I can't use
position:absolute
overflow
because they are available from Blackberry firmware 4.6 and up
things to try:
use the z-index to put it behind some other element
move it off the screen by absolute positioning
visbility: hidden
make the content "invisible" by setting background to foreground color (works only for text)
opacity: 0
but the real question is: why?
This is a common way:
margin-left: -9999;
How about:
visibility: hidden;
That should hide the DIV, (note how it will still be rendered but be invisible, that means it will take space in the document as if it was visible, but be invisible (unlike display:none; where the div will not be rendered)).
<div style="height:0;width:0;overflow:hidden;">
<!-- content here -->
</div>
Incidentally, this is what I do to preload images, which is nice because it doesn't use javascript.
Visibility:hidden won't do the same thing because some browsers are smart and won't make the request unless it thinks its actually visible.
Why not try the simple:
position: absolute;
left: -1000px;
I can't see why it wouldn't work.
I'm not sure of the percentages you're talking about that are using < 4.6, but if it's that important to you, then I can see a rationale for accepting that you can't please all the people all the time, and an acceptable cascading solution to this should be achievable. Probably with a link to explain the benefits of upgrading and enabling css.
height: 0;
overflow: hidden;
visibility: hidden;
color: #fff;
background: #fff;
BTW - you'd better make sure that you're css is good if you're telling someone to turn it on... :-)
What makes you think display: none is not supported before version 4.6? Did you test that, or are you going by their documentation?
I'm not a mobile developer either, so I'm just going by what I gleaned from the documentation.
The BlackBerry Browser 4.6 CSS Reference indeed mentions "Availability: BlackBerry® Device Software version 4.6 or later" for the display property, but their BlackBerry Browser 4.3 Content Developer Guide indicates that 4.3 already supported a very limited version of the display property, including display: none. Versions before 4.3 don't support the display property (again, going by the BlackBerry Browser developer documentation).
Can you assume your users do at least have firmware version 4.3, or is that just as unacceptable as assuming they have 4.6?
Have you tried simply setting the width and height to zero? I'm not familiar with the BlackBerry (Browser), but I'm sceptically assuming its CSS support is less than perfect, certainly on the older versions. I wouldn't be surprised if this worked:
.BBwarn {
display: none; /* for 4.6 and up */
width: 0px; /* for 4.3 */
height: 0px;
}
But then width and height are only supported on all elements starting from version 4.3. Before that they could only be applied to <button> and <img> tags and some <input> types (according to the documentation).
So perhaps the safest way to really make it work on all BlackBerry firmware versions is to use an image for the warning, and use CSS to set its width and height to zero.
If an image is not an option (due to lozalization issues or so, perhaps), an ugly hack might be to specify an empty/illegal image source and put the warning text in the alt attribute. I don't know if setting its width and height to zero would still hide that alt text then.
visibility: hidden; will work, but the space taken up by that particular div will still appear. If you are going to use the negative left-margin method, remember that you will need to set the object's position to absolute.
How about this:
clip: rect(0,0,0,0);
Note: Please note the clip property does not work if "overflow:visible" is used.
In your case:
<div class="BBwarn">
please activate your css support and a link
</div>
just add this css:
.BBwarn{
position: absolute;
clip: rect(0,0,0,0);
}
You could position it absolutely off the screen.
But I, also, am not a mobile developer.
I assume You don't want to use JavaScript because the Blackberrys don't support it.
What about if you did the opposite and displayed the block of code with JavaScript, rather than tried to hide it?
<script type="text/javascript"><!--
document.open();
document.writeln('<div class="BBwarn">');
document.writeln('please activate your css support and a link');
document.writeln('</div>');
document.close();
//--></script>
This is a bit of a hack, but would not display the text with disabled JavaScript...
You can do something like wise:
.class{
opacity:0; overflow:hidden; visibility: hidden; height:0;
}
for being more precise you can add :
color:transparent; background-color:transparent;
What exactly is wrong with (the earlier mentioned)
width: 0
height:0
visibility: hidden
width: 0 height:0 visibility: hidden
...Does not always work with firmware 2.2 and older. Sometimes you can get an element to be hidden, but it will reappear with certain keystrokes (like underscore, for instance).
Or you could use Please enable Javascript
And use an image that reads "Enable CSS" and style it using "display:none".
So that whenever the corresponding feature is enabled these warnings wont show.
Alternately, I presume you are using some server side code? You could try detecting for the most common known platforms that support specific versions of css/javascript and deliver content accordingly. You might not even have to write it all yourself.
I had a similar problem when I was trying to customize a select box using javascript in BlackBerry Curve 8530 (OS 5.0). But, the menu created couldn't be hidden because the css following properties still don't work:
display
overflow
position: absolute
visibility
z-index
And destroying and recreating the HTML elements didn't work either, so I got here and could solve my problem.
I know my answer isn't exactly about the question raised here, but once I got here when had problems, I think I'm not the only one with it happened and is going to.
Anyway, even if those css properties worked, what I needed was some code that could work on the most of the BB models.
My solution was made using all the answers found here. It was simple. I made two classes:
.element
{
width: 100px;
height: 100px;
font-size: 12px;
color: black;
background-color: transparent;
border: 1px solid black;
}
.element_hidden
{
width: 0px;
height: 0px;
font-size: 0px;
color: white;
background-color: white;
border: none;
}
Yes. I've made two of them for each kind of element I had in my page.
Initially, all classes are set to class="element_hidden", so when the mouse is over the select box menu, all the classes are changed to class="element" and they are shown and hidden as if they were made invisible/visible.
I hope this can be useful to someone! ;D
We can use the transform property to scale the element along the x and y axis.
. BBwarn{
transform : scale(0,0);
}
I used font size to obtain this without using display none
font-size: 0px;
As you said in question that you need solution for Blackberry version below 4.6 and there are very few CSS properties supported for Blackberry version below 4.6 so we can use some sort of hack for this purpose. Try and set the text color to whatever the background is or set font-size to 0. It's a hack, but it makes it invisible. Run the following snippet and let me know if its works for you.
.alert1 {
color: #fff; //3.8 or later
}
.alert2 {
font-size: 0; //3.8 or later
}
<b>Alert1</b>
<div class="alert1">
please activate your css support and a link
</div>
<b>Alert2</b>
<div class="alert2">
please activate your css support and a link
</div>