Top css Questions

List of Tags
803
kokos

In inline HTML, the table styles cellpadding and cellspacing can be set

<table cellspacing="1" cellpadding="1">

How would this be accomplished using a CSS stylesheet?

Answered By: Eric Nguyen ( 1027)

None of the answers here are complete, so I'll merge them into a comprehensive one.

First of all, you can control cellspacing by applying the border-spacing CSS property to your table. This will work in almost all popular browsers except for IE up through v7. For browsers which support it, this property will even allow separate horizontal and vertical spacing. If you need to support IE 5, 6, or 7, you're almost out of luck.

However, I say "almost" because these browsers still support the border-collapse property, which merges the borders of adjoining table cells. If you're trying to eliminate cellspacing (i.e. cellspacing="0") then border-collapse:collapse should have the same effect: no space between table cells. This support is buggy, though, as it does not override an existing cellspacing HTML attribute on the table element.

In short: for non-IE 5-7 browsers, border-spacing handles you. For IE, if your situation is just right (you want 0 cellspacing and your table doesn't have it defined already), you can use border-collapse:collapse.

table { 
  border-spacing:0;
  border-collapse:collapse;
}

Note: For a great overview of CSS properties that one can apply to tables and for which browsers, see this fantastic Quirksmode page.

For anchors that act like buttons (for example, Questions, Tags, Users, etc. at the top of the Stack Overflow page) or tabs, is there a CSS standard way to disable the highlighting effect if the user accidentally selects the text?

I realize this could be done with JavaScript, and a little googling yielded the Mozilla-only -moz-user-select option.

Is there a standard-compliant way to accomplish this with CSS, and if not, what is the "best practice" approach?

Answered By: Blowsie ( 1276)

All of the correct CSS variations are:

-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
665
Bno

It seems to be the general opinion that tables should not be used for layout in HTML.

Why?

I have never (or rarely to be honest) seen good arguments for this. The usual answers are:

  • It's good to separate content from layout
    But this is a fallacious argument; Cliche Thinking. I guess it's true that using the table element for layout has little to do with tabular data. So what? Does my boss care? Do my users care?

    Perhaps me or my fellow developers who have to maintain a web page care... Is a table less maintainable? I think using a table is easier than using divs and CSS.

    By the way... why is using a div or a span good separation of content from layout and a table not? Getting a good layout with only divs often requires a lot of nested divs.

  • Readability of the code
    I think it's the other way around. Most people understand HTML, few understand CSS.

  • It's better for SEO not to use tables
    Why? Can anybody show some evidence that it is? Or a statement from Google that tables are discouraged from an SEO perspective?

  • Tables are slower.
    An extra tbody element has to be inserted. This is peanuts for modern web browsers. Show me some benchmarks where the use of a table significantly slows down a page.

  • A layout overhaul is easier without tables, see css Zen Garden.
    Most web sites that need an upgrade need new content (HTML) as well. Scenarios where a new version of a web site only needs a new CSS file are not very likely. Zen Garden is a nice web site, but a bit theoretical. Not to mention its misuse of CSS.

I am really interested in good arguments to use divs + CSS instead of tables.

Answered By: Konrad Rudolph ( 498)

I'm going to go through your arguments one after another and try to show the errors in them.

It's good to separate content from layout But this is a fallacious argument; Cliché Thinking.

It's not fallacious at all because HTML was designed intentionally. Misuse of an element might not be completely out of question (after all, new idioms have developed in other languages, as well) but possible negative implications have to be counterbalanced. Additionally, even if there were no arguments against misusing the <table> element today, there might be tomorrow because of the way browser vendors apply special treatment to the element. After all, they know that “<table> elements are for tabular data only” and might use this fact to improve the rendering engine, in the process subtly changing how <table>s behave, and thus breaking cases where it was previously misused.

So what? Does my boss care? Do my users care?

Depends. Is your boss pointy-haired? Then he might not care. If she's competent, then she will care, because the users will.

Perhaps me or my fellow developers who have to maintain a web page care... Is a table less maintainable? I think using a table is easier than using divs and css.

The majority of professional web developers seem to oppose you[citation needed]. That tables are in fact less maintainable should be obvious. Using tables for layout means that changing the corporate layout will in fact mean changing every single page. This can be very expensive. On the other hand, judicious use of semantically meaningful HTML combined with CSS might confine such changes to the CSS and the pictures used.

By the way... why is using a div or a span good separation of content from layout and a table not? Getting a good layout with only divs often requires a lot of nested divs.

Deeply nested <div>s are an anti-pattern just as table layouts. Good web designers don't need many of them. On the other hand, even such deep-nested divs don't have many of the problems of table layouts. In fact, they can even contribute to a semantic structure by logically dividing the content in parts.

Readability of the code I think it's the other way around. Most people understand html, little understand css. It's simpler.

“Most people” don't matter. Professionals matter. For professionals, table layouts create many more problems than HTML + CSS. This is like saying I shouldn't use GVim or Emacs because Notepad is simpler for most people. Or that I shouldn't use LaTeX because MS Word is simpler for most people.

It's better for SEO not to use tables

I don't know if this is true and wouldn't use this as an argument but it would be logical. Search engines search for relevant data. While tabular data could of course be relevant, it's rarely what users search for. Users search for terms used in the page title or similarly prominent positions. It would therefore be logical to exclude tabular content from filtering and thus cutting the processing time (and costs!) by a large factor.

Tables are slower. An extra tbody element has to be inserted. This is peanuts for modern web browsers.

The extra element has got nothing to do with tables being slower. On the other hand, the layout algorithm for tables is much harder, the browser often has to wait for the whole table to load before it can begin to layout the content. Additionally, caching of the layout won't work (CSS can easily be cached). All this has been mentioned before.

Show me some benchmarks where the use of a table significantly slows down a page.

Unfortunately, I don't have any benchmark data. I would be interested in it myself because it's right that this argument lacks a certain scientific rigour.

Most web sites that need an upgrade need new content (html) as well. Scenarios where a new version of a web site only needs a new css file are not very likely.

Not at all. I've worked on several cases where changing the design was simplified by a separation of content and design. It's often still necessary to change some HTML code but the changes will always be much more confined. Additionally, design changes must on occasion be made dynamically. Consider template engines such as the one used by the WordPress blogging system. Table layouts would literally kill this system. I've worked on a similar case for a commercial software. Being able to change the design without changing the HTML code was one of the business requirements.

Another thing. Table layout makes automated parsing of websites (screen scraping) much harder. This might sound trivial because, after all, who does it? I was surprised myself. Screen scraping can help a lot if the service in question doesn't offer a WebService alternative to access its data. I'm working in bioinformatics where this is a sad reality. Modern web techniques and WebServices have not reached most developers and often, screen scraping is the only way to automate the process of getting data. No wonder that many biologists still perform such tasks manually. For thousands of data sets.

644
David Murdoch

Chrome supports the placeholder attribute on input[type=text] elements (others probably do too).

But the following CSS doesn't do diddly squat to the placeholder's value:

CSS:

input[placeholder], [placeholder], *[placeholder] {
   color:red !important;
}

HTML:

<input type="text" placeholder="Value" />

Value will still remain grey instead of red.

Is there a way to change the color of the placeholder text?

p.s. I'm already using the jQuery placeholder plugin for the browsers that don't support the placeholder attribute natively.

Answered By: toscho ( 1114)

Implementation

There are three different implementations: pseudo-elements, pseudo-classes, and nothing.

IE up to version 9 and Opera up to version 12 do not support any CSS selector for placeholders.

The discussion about the best implementation is still going on. Note the pseudo-elements act like real elements in the Shadow DOM. A padding on an input will not get the same background color as the pseudo-element.

CSS selectors

User agents are required to ignore a rule with an unknown selector. See Selectors Level 3:

a group of selectors containing an invalid selector is invalid.

So we need separate rules for each browser. Otherwise the whole group would be ignored by all browsers.

::-webkit-input-placeholder { /* WebKit browsers */
    color:    #999;
}
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
    color:    #999;
}
::-moz-placeholder { /* Mozilla Firefox 19+ */
    color:    #999;
}
:-ms-input-placeholder { /* Internet Explorer 10+ */
    color:    #999;
}

Usage notes

  • Be careful to avoid bad contrasts.
  • Note that placeholder text is just cut off if it doesn’t fit – size your input elements in em and test them with big minimum font size settings. Don’t forget translations: some languages need more room for the same word.
  • Browsers with HTML support for placeholder but without CSS support for that (like Opera) should be tested too.
  • Some browsers use additional default CSS for some input types (email, search). These might affect the rendering in unexpected ways. Use the properties -webkit-appearance and -moz-appearance to change that. Example:

    [type="search"] {
        -moz-appearance:    textfield;
        -webkit-appearance: textfield;
        appearance: textfield;
    }
    
587
Stanislav Shabalin

There're plenty of different CSS shapes over at http://css-tricks.com/examples/ShapesOfCSS/ and I'm particularly puzzled with a triangle:

Triangle

#triangle-up {
    width: 0;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 100px solid red;
}

So, how and why does it work?

Answered By: sdleihssirhc ( 919)

CSS Triangles: A Tragedy in Five Acts

As alex said, borders of equal width butt up against each other at 45 degree angles:

borders meet at 45 degree angles, content in middle

When you have no top border, it looks like this:

no top border

Then you give it a width of 0...

no width

...and a height of 0...

no height either

...and finally, you make the two side borders transparent:

transparent side borders

That results in a triangle.

The End

567
Lukas

How do I horizontally center a div in a div with CSS (if it's possible at all)?

The outer div has 100%:

<div id="outer" style="width:100%">  
    <div id="inner">Foo foo</div>
</div>
Answered By: Justin Poliey ( 680)

You can apply this CSS to the inner div:

#inner {
    width: 50%;
    margin: 0px auto;
}

Of course, you don't have to set the width to 50%. Any width less than the containing div will work. The margin: 0px auto is what does the actual centering.

If you are targeting IE8+, it might be better to have this instead:

#inner {
    display: table;
    margin: 0 auto;
}

It will make the inner element center horizontally and it works without setting a specific width.

494
Stijn Sanders

Is it possible, using CSS alone, to make the background of an element semi-transparent, but have the text of the element be non-transparent? I would like to accomplish this without having the text and the background be two separate elements. I've tried

<p style="position:absolute; background-color:green; filter:alpha(opacity=60); opacity:.6;">
  <span style="color:white; filter:alpha(opacity=100); opacity:1;">
    Hello world
  </span>
</p>

But it looks like child elements are subjected to the opacity of their parents, so opacity:1 is relative to the opacity:.6 of the parent.

Answered By: Georg Sch&#246;lly ( 627)

Either you use a semi-transparent PNG image or you use CSS 3:

background-color:rgba(255,0,0,0.5);

Here's an article from css3.info, Opacity, RGBA and compromise (2007-06-03).

445
One Crayon

This is one of the minor CSS problems that plagues me constantly. How do folks around StackOverflow vertically align checkboxes and their labels consistently cross-browser? Whenever I align them correctly in Safari (usually using vertical-align: baseline on the input), they're completely off in Firefox and IE. Fix it in Firefox, and Safari and IE are inevitably messed up. I waste time on this every time I code a form.

Here's the standard code that I work with:

<form>
    <div>
        <label><input type="checkbox" /> Label text</label>
    </div>
</form>

I usually use Eric Meyer's reset, so form elements are relatively clean of overrides. Looking forward to any tips or tricks that you have to offer!

Answered By: One Crayon ( 354)

After over an hour of tweaking, testing, and trying different styles of markup, I think I may have a decent solution. The requirements for this particular project were:

  1. Inputs must be on their own line
  2. Checkbox inputs need to align vertically with the label text similarly (if not identically) across all browsers
  3. If the label text wraps, it needs to be indented (so no wrapping down underneath the checkbox)

Before I get into any explanation, I'll just give you the code:

<form>
    <div>
        <label><input type="checkbox" /> Label text</label>
    </div>
</form>

<style type="text/css">
label {
    display: block;
    padding-left: 15px;
    text-indent: -15px;
}
input {
    width: 13px;
    height: 13px;
    padding: 0;
    margin:0;
    vertical-align: bottom;
    position: relative;
    top: -1px;
    *overflow: hidden;
}
</style>

Here is the working example in JSFiddle: http://jsfiddle.net/t8EGn/6/

This code assumes that you're using a reset like Eric Meyer's that doesn't override form input margins and padding (hence putting margin and padding resets in the input CSS). Obviously in a live environment you'll probably be nesting/overriding stuff to support other input elements, but I wanted to keep things simple.

Things to note:

  • The *overflow declaration is an inline IE hack (the star-property hack). Both IE 6 and 7 will notice it, but Safari and Firefox will properly ignore it. I think it might be valid CSS, but you're still better off with conditional comments; just used it for simplicity.
  • As best I can tell, the only vertical-align statement that was consistent across browsers was vertical-align: bottom. Setting this and then relatively positioning upwards behaved almost identically in Safari, Firefox and IE with only a pixel or two of discrepancy.
  • The major problem in working with alignment is that IE sticks a bunch of mysterious space around input elements. It isn't padding or margin, and it's damned persistent. Setting a width and height on the checkbox and then overflow: hidden for some reason cuts off the extra space and allows IE's positioning to act very similarly to Safari and Firefox.
  • Depending on your text sizing, you'll no doubt need to adjust the relative positioning, width, height, and so forth to get things looking right.

Hope this helps someone else! I haven't tried this specific technique on any projects other than the one I was working on this morning, so definitely pipe up if you find something that works more consistently.

438
Nathan Smith

How can I change a CSS class of an HTML element in response to an onClick event using JavaScript?

Answered By: Peter Boughton ( 696)

Adding and Removing Classes, with simple cross-browser JavaScript

The standard JavaScript way to select an element is using document.getElementById("Id"), which is what the following examples use - you can of course obtain elements in other ways, and in the right situation may simply use this instead - however, going into detail on this is beyond the scope of the answer.

To change all classes for an element:

To replace all existing classes with one or more new classes, set the className attribute:

document.getElementById("MyElement").className = "MyClass";

(You can specify a space-delimited list of elements.)

To add an additional class to an element:

To add a class to an element, without removing/affecting existing values, append a space and the new classname, like so:

document.getElementById("MyElement").className += " MyClass";

To remove a class from an element:

To remove a single class to an element, without affecting other potential classes, a simple regex replace is required:

document.getElementById("MyElement").className =
   document.getElementById("MyElement").className.replace
      ( /(?:^|\s)MyClass(?!\S)/g , '' )
/* code wrapped for readability - above is all one statement */

An explanation of this regex is as follows:

(?:^|\s) # match the start of the string, or any single whitespace character

MyClass  # the literal text for the classname to remove

(?!\S)   # negative lookahead to verify the above is the whole classname
         # ensures there is no non-space character following
         # (i.e. must be end of string or a space)

The g flag tells the replace to repeat as required, in case the class name has been added multiple times.

To check if a class is already applied to an element:

The same regex used above for removing a class can also be used as a check as to whether a particular class exists:

if ( document.getElementById("MyElement").className.match(/(?:^|\s)MyClass(?!\S)/) )


Assigning these actions to onclick events:

Whilst it is possible to write JavaScript directly inside the HTML event attributes (such as onclick="this.className+=' MyClass'") this is not recommended behaviour. Especially on larger applications, more maintainable code is achieved by separating HTML markup from JS interaction logic.

The first step to achieving this is by creating a function, and calling the function in the onclick attribute, for example:

<script type="text/javascript">
    function changeClass()
    {
        // code examples from above
    }
</script>
...
<button onclick="changeClass()">My Button</button>

(It is not required to have this code in script tags, this is simply for brevity of example, and including the JS in a distinct file may be more appropriate.)

The second step is to move the onclick event out of the HTML and into JavaScript, for example using addEventListener

<script type="text/javascript">
    function changeClass()
    {
        // code examples from above
    }

    window.onload = function()
    {
        document.getElementById("MyElement").addEventListener( 'click' , changeClass );
    }
</script>
...
<button id="MyElement">My Button</button>

(Note that the window.onload part is required so that the contents of that function are executed after the HTML has finished loading - without this, the MyElement might not exist when the JS is called, so that line would fail.)


JavaScript Frameworks

The above code is all in standard JavaScript, however it is common practise to use a framework to simplify common tasks, as well as benefit from fixed bugs and edge cases that you might not think of when writing your code.

Whilst some people consider it overkill to add a ~50KB framework for simply changing a class, if you are doing any substantial amount of JavaScript work, or anything that might have unusual cross-browser behaviour, it is well worth considering a framework.

The examples above have been reproduced below using jQuery, probably the most commonly used framework (though there are other frameworks worth investigating too).

(Note that $ here is the jQuery object.)

Changing Classes with jQuery:

$('#MyElement').addClass('MyClass');

$('#MyElement').removeClass('MyClass');

if ( $('#MyElement').hasClass('MyClass') )

In addition, jQuery provides a shortcut for adding a class if it doesn't apply, or removing a class that does:

$('#MyElement').toggleClass('MyClass');


Assigning a function to a click event with jQuery:

$('#MyElement').click(changeClass);

or, without needing an id:

$(':button:contains(My Button)').click(changeClass);


HTML5 Techniques for changing classes

Modern browsers have added classList which provides methods to make it easier to manipulate classes without needing a framework:

document.getElementById("MyElement").classList.add('class');

document.getElementById("MyElement").classList.remove('class');

if ( document.getElementById("MyElement").classList.contains('class') )

document.getElementById("MyElement").classList.toggle('class');

Unfortunately, these do not work in Internet Explorer prior to v10, though there is a shim to add support for it to IE8 and IE9, available from this page.

Why won't vertical-align: middle work? And yet, vertical-align: top does work.

<div>
   <img style="width:30px;height:30px">
   <span style="vertical-align:middle">Doesn't work.</span>
</div>

CSS is so annoying.

Answered By: Michael Haren ( 527)

Actually, in this case it's quite simple: apply the vertical align to the image. Since it's all in one line, it's really the image you want aligned, not the text.

<!-- moved "vertical-align:middle" style from span to img -->
<div>
   <img style="width:30px;height:60px;vertical-align:middle">
   <span style="">Works.</span>
</div>

Tested in FF3.