In an HTML table, the cellpadding and cellspacing can be set like this:
<table cellspacing="1" cellpadding="1">
How can the same be accomplished using CSS?
Basics
For controlling "cellpadding" in CSS, you can simply use padding on table cells. E.g. for 10px of "cellpadding":
td {
padding: 10px;
}
For "cellspacing", you can apply the border-spacing CSS property to your table. E.g. for 10px of "cellspacing":
table {
border-spacing: 10px;
border-collapse: separate;
}
This property will even allow separate horizontal and vertical spacing, something you couldn't do with old-school "cellspacing".
Issues in IE ≤ 7
This will work in almost all popular browsers except for Internet Explorer up through Internet Explorer 7, where you're almost out of luck. 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 (that is, 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-Internet Explorer 5-7 browsers, border-spacing handles you. For Internet Explorer, 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.
Default
The default behavior of the browser is equivalent to:
table {border-collapse: collapse;}
td {padding: 0px;}
Cellpadding
Sets the amount of space between the contents of the cell and the cell wall
table {border-collapse: collapse;}
td {padding: 6px;}
Cellspacing
Controls the space between table cells
table {border-spacing: 2px;}
td {padding: 0px;}
Both
table {border-spacing: 2px;}
td {padding: 6px;}
Both (special)
table {border-spacing: 8px 2px;}
td {padding: 6px;}
Note: If there is border-spacing set, it indicates border-collapse property of the table is separate.
Try it yourself!
Here you can find the old HTML way of achieving this.
table
{
border-collapse: collapse; /* 'cellspacing' equivalent */
}
table td, table th
{
padding: 0; /* 'cellpadding' equivalent */
}
Setting margins on table cells doesn't really have any effect as far as I know. The true CSS equivalent for cellspacing is border-spacing - but it doesn't work in Internet Explorer.
You can use border-collapse: collapse to reliably set cell spacing to 0 as mentioned, but for any other value I think the only cross-browser way is to keep using the cellspacing attribute.
This hack works for Internet Explorer 6 and later, Google Chrome, Firefox, and Opera:
table {
border-collapse: separate;
border-spacing: 10px; /* cellspacing */
*border-collapse: expression('separate', cellSpacing = '10px');
}
table td, table th {
padding: 10px; /* cellpadding */
}
The * declaration is for Internet Explorer 6 and 7, and other browsers will properly ignore it.
expression('separate', cellSpacing = '10px') returns 'separate', but both statements are run, as in JavaScript you can pass more arguments than expected and all of them will be evaluated.
For those who want a non-zero cellspacing value, the following CSS worked for me, but I'm only able to test it in Firefox.
See the Quirksmode link posted elsewhere for compatibility details. It seems it may not work with older Internet Explorer versions.
table {
border-collapse: separate;
border-spacing: 2px;
}
The simple solution to this problem is:
table
{
border: 1px solid #000000;
border-collapse: collapse;
border-spacing: 0px;
}
table td
{
padding: 8px 8px;
}
Also, if you want cellspacing="0", don't forget to add border-collapse: collapse in your table's stylesheet.
Wrap the contents of the cell with a div and you can do anything you want, but you have to wrap every cell in a column to get a uniform effect. For example, to just get wider left & right margins:
So the CSS will be,
div.cellwidener {
margin: 0px 15px 0px 15px;
}
td.tight {
padding: 0px;
}
<table border="0">
<tr>
<td class="tight">
<div class="cellwidener">My content</div>
</td>
</tr>
</table>
Yes, it's a hassle. Yes, it works with Internet Explorer. In fact, I've only tested this with Internet Explorer, because that's all we're allowed to use at work.
This style is for full reset for tables - cellpadding, cellspacing and borders.
I had this style in my reset.css file:
table{
border:0; /* Replace border */
border-spacing: 0px; /* Replace cellspacing */
border-collapse: collapse; /* Patch for Internet Explorer 6 and Internet Explorer 7 */
}
table td{
padding: 0px; /* Replace cellpadding */
}
TBH. For all the fannying around with CSS you might as well just use cellpadding="0" cellspacing="0" since they are not deprecated...
Anyone else suggesting margins on <td>'s obviously has not tried this.
Simply use CSS padding rules with table data:
td {
padding: 20px;
}
And for border spacing:
table {
border-spacing: 1px;
border-collapse: collapse;
}
However, it can create problems in older version of browsers like Internet Explorer because of the diff implementation of the box model.
From what I understand from the W3C classifications is that <table>s are meant for displaying data 'only'.
Based on that I found it a lot easier to create a <div> with the backgrounds and all that and have a table with data floating over it using position: absolute; and background: transparent;...
It works on Chrome, Internet Explorer (6 and later) and Mozilla Firefox (2 and later).
Margins are used (or meant anyways) to create a spacer between container elements, like <table>, <div> and <form>, not <tr>, <td>, <span> or <input>. Using it for anything other than container elements will keep you busy adjusting your website for future browser updates.
CSS:
selector{
padding:0 0 10px 0; // Top left bottom right
}
You can easily set padding inside the table cells using the CSS padding property. It is a valid way to produce the same effect as the table's cellpadding attribute.
table,
th,
td {
border: 1px solid #666;
}
table th,
table td {
padding: 10px;
/* Apply cell padding */
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Set Cellpadding in CSS</title>
</head>
<body>
<table>
<thead>
<tr>
<th>Row</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Clark</td>
<td>Kent</td>
<td>clarkkent#mail.com</td>
</tr>
<tr>
<td>2</td>
<td>Peter</td>
<td>Parker</td>
<td>peterparker#mail.com</td>
</tr>
<tr>
<td>3</td>
<td>John</td>
<td>Rambo</td>
<td>johnrambo#mail.com</td>
</tr>
</tbody>
</table>
</body>
</html>
Similarly, you can use the CSS border-spacing property to apply the spacing between adjacent table cell borders like the cellspacing attribute. However, in order to work border-spacing the value of border-collapse property muse be separate, which is default.
table {
border-collapse: separate;
border-spacing: 10px;
/* Apply cell spacing */
}
table,
th,
td {
border: 1px solid #666;
}
table th,
table td {
padding: 5px;
/* Apply cell padding */
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Set Cellspacing in CSS</title>
</head>
<body>
<table>
<thead>
<tr>
<th>Row</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Clark</td>
<td>Kent</td>
<td>clarkkent#mail.com</td>
</tr>
<tr>
<td>2</td>
<td>Peter</td>
<td>Parker</td>
<td>peterparker#mail.com</td>
</tr>
<tr>
<td>3</td>
<td>John</td>
<td>Rambo</td>
<td>johnrambo#mail.com</td>
</tr>
</tbody>
</table>
</body>
</html>
Try this:
table {
border-collapse: separate;
border-spacing: 10px;
}
table td, table th {
padding: 10px;
}
Or try this:
table {
border-collapse: collapse;
}
table td, table th {
padding: 10px;
}
I used !important after the border-collapse like
border-collapse: collapse !important;
and it works for me in IE7. It seems to override the cellspacing attribute.
Say that we want to assign a 10px "cellpadding" and a 15px "cellspacing" to our table, in a HTML5-compliant way. I will show here two methods giving really similar outputs.
Two different sets of CSS properties apply to the same HTML markup for the table, but with opposite concepts:
the first one uses the default value for border-collapse (separate) and uses border-spacing to provide the cellspacing,
the second one switches border-collapse to collapse and uses the border property as the cellspacing.
In both cases, the cellpadding is achieved by assigning padding:10px to the tds and, in both cases, the background-color assigned to them is only for the sake of a clearer demo.
First method:
table{border-spacing:15px}
td{background-color:#00eb55;padding:10px;border:0}
<table>
<tr>
<td>Header 1</td><td>Header 2</td>
</tr>
<tr>
<td>1</td><td>2</td>
</tr>
<tr>
<td>3</td><td>4</td>
</tr>
</table>
Second method:
table{border-collapse:collapse}
td{background-color:#00eb55;padding:10px;border:15px solid #fff}
<table>
<tr>
<td>Header 1</td><td>Header 2</td>
</tr>
<tr>
<td>1</td><td>2</td>
</tr>
<tr>
<td>3</td><td>4</td>
</tr>
</table>
td {
padding: npx; /* For cellpadding */
margin: npx; /* For cellspacing */
border-collapse: collapse; /* For showing borders in a better shape. */
}
If margin didn't work, try to set display of tr to block and then margin will work.
I have some rows that using ajax to get data, if I use a tag, the browser will be refresh and some data will lost. Then I just use td tag, but I want to make it look like a tag (color, cursor a hand)
Here my code:
<td style="color: green;" onclick="myFunction(this)">hello</td>
// failed with: <td style="color: green;" onclick="myFunction(this)">hello</td>
You can use following css to give td look and feel like a.
td {
color: #337ab7;
text-decoration: none;
cursor: pointer;
}
td:focus, td:hover {
color: #23527c;
text-decoration: underline;
}
Color should work the way you have it.
for cursor you could try
td {
cursor: pointer;
}
You should use a, but return false after your function and use # as href value:
hello
While you could do that using the cursor: pointer CSS-property, I'd rather use the <a> tag and set a click event handler like this:
<a id="clickable">Click</a>
<script>
document.getElementById("clickable").addEventListener('click', function(e) {
alert("Clicked")
e.preventDefault()
return false
})
</script>
See a working example here
A <td> tag is actually part of the <table> tag and should not be used outside it.
What you're better off doing is simply creating a new button using a <div> element and some CSS
.button {
display: inline-block;
padding: 5px 12px;
background: #09c;
color: #eee;
cursor: pointer;
border-radius: 3px;
border: 1px solid #28f;
}
<div class="button">My button text</div>
display: inline-block causes the <div> element to not take up the entire width of the page (just wrap the contents).
cursor: pointer will make the cursor literally look like a pointer when hovering over the element.
Not using a table tag here makes much more sense since you're not displaying a table (From what I can see in the question).
And that's pretty much it!
I have a table and within each cell with reside one single div with a class that is prefixed with perc- and will contain on number ranging from 0 to 100. For instance perc-60 which would equate to 60%.
I can do this in CSS by generating a SASS loop and processing 100 variants on the perc- class. For purposes of learning I'd like to know how I can achieve an inline style via Javascript where by I can set the width of the div based on the number in the class. The numbers get applied via a backend system out of my control, but will related to some data from the user.
Example markup:
<table>
<tr>
<td class="perc-60"><div></div></td>
</tr>
<tr>
<td class="perc-15"><div></div></td>
</tr>
<tr>
<td class="perc-45"><div></div></td>
</tr>
<tr>
<td class="perc-16"><div></div></td>
</tr>
<tr>
<td class="perc-88"><div></div></td>
</tr>
<tr>
<td class="perc-79"><div></div></td>
</tr>
<tr>
<td class="perc-98"><div></div></td>
</tr>
</table>
At the moment I use a SASS loop to go through all the classes and target the divs width within the td.
I got carried away, I made it fancy, sorry. I used JavaScript as originally requested. There are comments for each step of the script.
var td = selArray('td'); // Make an array of <td> selectors
for (var i = 0; i < td.length; i++) { // Loop thru array
var perc = td[i].className; // Find each <td> class
//console.log('Cell '+i+': '+perc);
var cell = document.querySelector('.' + perc); // Create DOM Object for <td>
//console.log(cell.className);
var div = cell.querySelector('div'); // Create DOM Object for <td> > <div>
var str = perc.split('-').pop(); // Strip 'perc-' from class, now a String "number" remains
/* http://stackoverflow.com/a/3568968/2813224 */
var divWidth = str + "%"; // Add a "%" to String "number"
//console.log(divWidth);
div.style.width = divWidth; // Assign String "number" as <div> width
//console.log(div.style.width);
div.innerHTML = divWidth; // Insert width as text into <div>
}
/* This function will accept a selector (ex. #elementID, .elementCLASS, elementTAGNAME, etc.) like jQuery does and then returns an array of selectors that matched.
https://developer.mozilla.org/en-US/docs/Web/API/NodeListhttps://developer.mozilla.org/en-US/docs/Web/API/NodeList */
function selArray(sel) {
var eleArr = Array.prototype.slice.call(document.querySelectorAll(sel));
return eleArr;
}
html {
box-sizing: border-box;
font: 900 16px/1.5'Source Code Pro';
}
*,
*:before,
*:after {
box-sizing: inherit;
margin: 0;
padding: 0;
border: 0;
}
body {
height: 100vh;
width: 100vw;
background: #666;
}
table.x {
padding: 0;
box-shadow: 0 1px 9px 1px #ccc;
border-radius: 6px;
margin: 20px auto;
width: 80%;
table-layout: fixed !important;
}
.x th {
color: #FFF;
background: #086ac8;
padding: 10px;
text-align: center;
vertical-align: middle;
height: 2em;
}
.x tr:nth-child(odd) {
background-color: #333;
color: #FFF;
}
.x tr:nth-child(even) {
background-color: #2e90ef;
color: #333;
}
.x td {
border-style: solid;
border-width: 1px;
border-color: #57acff;
padding: 5px;
text-align: left;
vertical-align: middle;
height: 2em;
}
thead th:first-child {
border-top-left-radius: 6px;
}
thead th:last-child {
border-top-right-radius: 6px;
}
.x tbody tr:last-child th:first-child {
border-bottom-left-radius: 6px;
}
.x tbody tr:last-child td:first-child {
border-bottom-left-radius: 6px;
}
.x tbody tr:last-child td:last-child {
border-bottom-right-radius: 6px;
}
.x td div {
height: 1.5em;
outline: 1px solid #FC0;
background: hsla(60, 100%, 50%, .3);
vertical-align: middle;
}
<table class='x'>
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td class="perc-60">
<div></div>
</td>
</tr>
<tr>
<td class="perc-15">
<div></div>
</td>
</tr>
<tr>
<td class="perc-45">
<div></div>
</td>
</tr>
<tr>
<td class="perc-16">
<div></div>
</td>
</tr>
<tr>
<td class="perc-88">
<div></div>
</td>
</tr>
<tr>
<td class="perc-79">
<div></div>
</td>
</tr>
<tr>
<td class="perc-98">
<div></div>
</td>
</tr>
</tbody>
</table>
Here is a jQuery solution that would iterate through the td's and use the class as a parameter:
Hopefully your backend is already outputting single-digit values preceded by a zero.
$(document).ready(function(){
$("td").each(function(){
$(this).width($(this).attr("class").substring(5,7) + "%");
});
});
Make sure your tds are already using the right box-sizing:
td {
box-sizing: border-box;
}
Classes are abstractions which can be re-used across elements and easily bring in sets of properties. This is more modular and maintainable, since the classes can be changed or added to and the changes automatically propagate to all the elements that use them.
There is also a CSS architectural style which involves classes with very small number, even just one, property ("micro-classes"). In this case, it is not about modularity or ability to change the class; it is more a matter of syntactic sugar and compactness. For instance, I can define a class absolute which is defined as .absolute { position: absolute; }, then apply it to an HTML element by simply saying class='absolute', instead of style='position: absolute; '.
In your case, there is no advantage of using classes, especially if you plan to introduce additional preprocessor machinery to generate all of them. What you propose is exactly equivalent to merely putting a style='width: 60%; ' attribute on the element. And that is precisely what you should do.
Putting in-line style attributes directly on HTML elements is not "evil", in the sense that eval is, for example. It's a practice which has been deprecated to help encourage people to write modular, orthogonal style rules independent of the HTML. However, there's absolutely nothing wrong with it if the style is specific to the particular element. In fact, in such cases, it can be be considered bad design to separate and externalize classes whose only purpose is to assign one or more properties to a specific HTML element.
tried to apply this answer to make change the class of the cells in my table on click, yet it doesn't work :(
$('td.link').click(function() {
$('td.button_active').removeClass('button_active');
$('td.link').addClass('button');
$(this).removeClass('button');
$(this).addClass('button_active')
})
My example code in jsfiddle is here..
Could someone take a short look and point what to change?
I am trying to make font red and change background image of clicked cell, other cells leaving with (or returning to) grey font and default backround image.
Thank you in advance!
Valdas
Because you've included MooTools instead of jQuery ;)
Check out this fiddle. It works when using jquery...
$('td.link').click(function() {
$('td.button_active').removeClass('button_active');
$('td.link').addClass('button');
$(this).removeClass('button');
$(this).addClass('button_active')
});
Edit
Here you go, a proper version. What I've done: put buttons inside the table cell (instead of transforming table cells into buttons), used an active class for the active button (instead of copying the button css to the active_button class), and altered the javascript a bit (less lines = nice :))
Check it out here (fiddle)
And the relevant code:
HTML
<table>
<tr>
<td>Link One</td>
</tr>
<tr>
<td>Link Two</td>
</tr>
<tr>
<td>Link Three</td>
</tr>
<tr>
<td>Link Four</td>
</tr>
</table>
CSS
.button {
display: block;
width: 113px;
height: 30px;
text-decoration: none;
background-image: url(http://www.verslomonitorius.lt/uploads/2/1/9/2/21922640/vm_button.svg);
background-repeat: no-repeat;
background-size: 138px 33px;
border: 1px solid #e6e6e6;
text-align: right;
padding: 0 25px 0 0;
font: 16px/30px 'Ubuntu';
color: #737373;
}
.active {
background-image: url(http://www.verslomonitorius.lt/uploads/2/1/9/2/21922640/vm_button_active.svg);
color: #ff0000;
cursor: default
}
.button:not(.active):hover {
background-image: url(http://www.verslomonitorius.lt/uploads/2/1/9/2/21922640/vm_button_hover.svg);
color: #000000;
}
Javascript
$('a.link').click(function(e) {
e.preventDefault();
$('a.active').removeClass('active');
$(this).addClass('active')
});
Note: In a live version, don't forget to wrap your javascript in a $.ready or closure
Be more accurate with libraries defined in jsfiddle. Here is what you need.
$('td.link').click(function() {
$('td.button_active').each(function(index) {
$(this).removeClass('button_active');
});
$('td.link').each(function(index) {
$(this).addClass('button')
});
$(this).removeClass('button');
$(this).addClass('button_active')
})
I'm using jQuery to addClass to a hovered over div...but the background color won't change. I'm guessing it's because it has previously been assigned a background-color in CSS? Other properties (border) on the hover class appear when hovering so addClass is working.
How can/should I make this work?
jQuery
$('.pick1-box').hover(
-> $(this).addClass('hover')
-> $(this).removeClass('hover')
)
CSS
.pick1-box, .pick2-box {
...
background: #eee;
...
}
.hover {
background-color: yellow;
border: 1px solid red;
}
html
...
<li class='nominee clearfix' id='146'>
<div class='candidate'>
<img alt="Enders" height="80" src="/assets/25803sm.jpg" />
Dick Waddington
</div>
<div class='pick-boxes'>
<div class='pick1-box'>
1
</div>
<div class='pick2-box'>
2
</div>
</div>
</li>
...
It depends how you're loading jquery and code but try this:
.hover {
background-color: yellow !important;
border: 1px solid red;
}
You can try re-ordering or adding an important to your CSS, or you could do something like:
$('.pick1-box').hover($(this).attr('style', 'background-color: yellow;border: 1px solid red;'),$(this).removeAttr('style'));
since element styles take precedence.
The problem, as you've stated, is because the style has been overridden in the style attribute of the element being affected. You have a couple of options:
Don't change the element's css directly.
Use !important on the settings you absolutely need to override element styles.
Change the element's css directly, but remove them once you're done with them.
You could make the 2nd rule more specific:
.pick1-box.hover, .pick2-box.hover {
background-color: yellow;
border: 1px solid red;
}
css specificity
This assumes that your .hover css actually occurs prior to the .pick1-box rule as these have equal specificity, the one which occurs later will have precedence.