css selectors to apply rules to multiple class of similar element - html

I have a simple table
<tr>
<td class="first">I am the first</td>
<td class="second">You are the second</td>
<td class="third">He is third</td>
<td class="fourth">Someone else is fourth</td>
<td class="fifth">That guy is fifht</td>
<td class="sixth">Who care's about sixth</td>
</tr>
I want to apply css rules on some of classes in td only. I can write something like-
td.first, td.fourth, td.fifth
{
color:purple;
}
This works. Or i can use classes. I was wondering is there any efficient/ better way to write selectors in such case.
My concern:
Is browser, is going to look for all class and then search for td for each comma separation. That means it going to find all three classes and then evaluate tag. Is there any way that browser will find all three classes and then matches the tag other than using a single class.

Addressing Your Concern
You state:
My concern: Is browser, is going to look for all td for each comma
separation and find the class match. That means it going to find all
td tags three times. If this is true, how can i make browser to search
for td tags once and then find class matches.
But that is not how css evaluates, as it goes from right to left. In the case you give:
td.first, td.fourth, td.fifth
{
color:purple;
}
So it will not search "three times" through td elements. Rather, it will match the .first class in your document (where ever it is), then check to see if it is applied to td element, and if so, match. Then evaluate .fourth, etc. in a similar fashion.
So if your concern is iterations through td elements, then your concern is invalid. Your code is efficient as it is.

For specific properties, you can create separate classes.
For example, in your case, you can make a class .color and write like this:
<tr>
<td class="first color">I am the first</td>
<td class="second">You are the second</td>
<td class="third">He is third</td>
<td class="fourth color">Someone else is fourth</td>
<td class="fifth color">That guy is fifht</td>
<td class="sixth">Who care's about sixth</td>
</tr>
.color{color:purple;}

You can use the :nth-child property to achieve the same without giving all these different classes to your TDs
i.e:
td:nth-child(1),
td:nth-child(4),
td:nth-child(5) {
color:purple;
}

Related

Combination of :first-child and #id selectors in :not() doesn't work

I am having trouble with :not() css selector. I check already on stackoverflow, but nothing is working. The problem is when I combine :first-child selector with id selector. I am working with Bitrix CRM, so I need to override some of its css, for this purpose I use "!important" (hardcore).
Here is a code:
.crm-offer-info-table tr:not(:first-child) {
float:right!important;width:49%}
.crm-offer-info-table tr:nth-child(2n+2):not(#section_contact_info_contents>tr) {
float: left!important;
padding-right: 10px;
width:49%
}
HTML part
<table id="section_contact_info_contents" class="crm-offer-info-table"><tbody>
<tr id="section_contact_info">
<td colspan="5">
..some code..
</td>
</tr>
<tr id="email_wrap" class="crm-offer-row">
<td class="crm-offer-info-drg-btn"></td>
<td class="crm-offer-info-left">
</td><td class="crm-offer-info-right"></td>
<td class="crm-offer-info-right-btn"></td>
<td class="crm-offer-last-td"></td>
</tr>
<tbody>
</table>
http://jsfiddle.net/d990f0a1/
So, the main question is .crm-offer-info-table tr:not(:first-child, #section_contact_info_contents>tr){} it doesn't work, I need to somehow combine these 2 selectors in :not(), and all this must be done in css too.
As the :not specs says, it works with simple selectors and #section_contact_info_contents>tr is not; you can split it using 2 :not selectors in this way:
.crm-offer-info-table:not(#section_contact_info_contents) tr:not(:first-child){...}
tr:nth-child(2n+2):not(#section_contact_info_contents>tr) doesn't make sense since your table only has 2 rows. Putting aside what jakopo87 answered just for a minute (jakopo87 is right about simple selectors), let's consider what this rule set is saying:
.crm-offer-info-table tr:nth-child(2n+2)
what I think you mean is:
ANY even numbered row that is inside of ANY table which is class="crm-offer-info-table"...
If that's what you meant, then this is how it should be:
.crm-offer-info-table> tbody >tr:nth-child(2n)
Next is this:
:not(#section_contact_info_contents>tr)
What I think you mean is:
...BUT exclude ALL rows inside a UNIQUE table which is
id="section_contact_info_contents".
If that is in fact your intention, then this is how it should be:
:not(#section_contact_info_contents> tbody >tr);
Of course if you exclude ALL rows of a table, that's basically excluding the table itself (in this context at least). So I suggest (as did jakopo87) you use a less verbose rule set:
:not(#section_ contact_info_contents *) or even :not(#section_contact_info_contents)
If you must use CSS rather than JS, then try using nth-of-type instead. Then you won't have to remember that tbody is the child of table, and tr is the child of tbody.
If I remember correctly you wanted the td that has a textarea to be in it's own column. Try display: table-column on the tr or td. Sorry I can't be more specific, but the info you posted does not include a full layout I suspect. Without the proper knowledge of the layout, advice on HTML/CSS is like horseshoes and hand grenades.

How to remove a html table particular column to make other datas visible(responsive) using media queries?

I have a table I want to make it look good in mobile view. What I thought is I can remove the unwanted data so that remaining data will be visible in mobile devices.
So I decided to give display:none; to unwanted column which is first in this case. I have a problem in doing this. When I give display:none to particular column data I get the empty space for the upper column because it doesn't have class to give display:none;
I cannot edit the source of markup, so is there a way to remove the column for mobile devices using media queries alone? That is CSS alone?
If possible, how to do it?
HTML
<table border="1">
<tr>
<th>
</th>
<th>
head1
</th>
<th>
head2
</th>
</tr>
<tr>
<td class="un">
unwanted-datas
</td>
<td>
datas
</td>
<td>
datas
</td>
</tr>
<tr>
<td class="un">
unwanted-datas
</td>
<td>
datas
</td>
<td>
datas
</td>
</tr>
<tr>
<td class="un">
unwanted-datas
</td>
<td>
datas
</td>
<td>
datas
</td>
</tr>
</table>
CSS
#media (max-width:480px) {
.un{
display:none;
}
}
JSFIDDLE
NOTE: Resize the output window less than 480px to see the effect.
CSS only solution:
http://jsfiddle.net/2YEzP/1/
I recommend you use another class/ID in front of the proposed selectors below, like this: .class123 table tr th:nth-child(1)
or: table.class45 tr th:nth-child(1)
Otherwise you could break other tables on the site!
#media (max-width:480px) {
table tr th:nth-child(1),
.un{
display:none;
}
}
The :nth-child() selector is supported in all major browsers, except IE8 and earlier.
jQuery solution:
It combines the CSS solution and adds jQuery to add support for older browsers. I recommend just that one!
http://jsfiddle.net/aykXG/1/
$( document ).ready(function() {
$( "table tr th:nth-child(1)" ).addClass( "un" );
});
Same note as above: I recommend you use another class/ID in front of the proposed selectors below, like this: .class123 table tr th:nth-child(1)
or: table.class45 tr th:nth-child(1)
This should be a unique selector and will make sure you won't affect another table/cells...
(The solutions keep the HTML unchanged, as requested.)
Trying using
CSS
#media (max-width:480px) {
.un{
visibility:hidden;
}
}
http://jsfiddle.net/LVzjP/
Try adding the .un class to the corresponding th element:
<th class="un">
</th>
http://jsfiddle.net/h9LN7/3/
edit
Since you're unable to edit the markup, you could try something with :nth-child() like so:
tr th:nth-child(1), tr td:nth-child(1){
display: none;
}
With the above solution, the entire first column will be set to display none without even needing an .un class
You have gotten what you asked for, and this demo only shows the effects of nth-child. Since you can't edit the markup the way is to use nth-child, I have used it for a while now and just loving it.
With nth-child and jquery you can set class-name so you or later person can keep a better eye on the elements
$('table tr td:first-child').attr('class', 'un');
This sets class name 'un' every first td columns in your table markup.
Or if you want to go for the css way, and wasnt to sure if you wanted to remove the head or not, so i keept it like this:
http://jsfiddle.net/Yb67s/1/

Can I include td { } in an inline style attribute of my table?

I'm working with a content management system that doesn't allow me to alter the head of the pages I'm working with. The page I'm creating will be edited by others using a WYSIWYG editor and will include a table where users can upload new documents. I want to style this with CSS so that I can give one command to put a line between each row (and this won't need to be done every time by each user - since they likely won't know how), but every time I do this it doesn't show anything. My code attempt is below, is this possible?
<table width=600px cellSpacing=2 cellPadding=2 style="td {border-bottom: solid 1px black;" }">
Not that I'm aware of. But you can do this
<style type="text/css">
.specialtable td {
border-bottom: 1px solid black;
}
</style>
<table width=600px cellSpacing=2 cellPadding=2 class="specialtable">
...
</table>
This will ensure that only this specific table's <td/> elements will be styled according to your needs. Note: according to the w3c specs, <style/> is only allowed within the <head/> element of your document. But in many browsers, it still works if you put it anywhere in the <body/>. Since you're looking for a kind of hack, this may be a viable solution for you
You can use frame and rules, two lesser-known attributes of the table element.
<table cellpadding="3" cellspacing="0" frame="below" rules="rows">
<tr><td>one</td><td>two</td></tr>
<tr><td>three</td><td>four</td></tr>
<tr><td>five</td><td>six</td></tr>
</table>
See jsFiddle.
Or if you only want lines in between the rows and not below the bottom one, leave out frame="below".
This won't work in all browsers though.

How to hide columns in HTML table?

I have created a table in ASPX. I want to hide one of the columns based on the requirement but there is no attribute like visible in the HTML table building. How can I solve my problem?
You need to use Style Sheet for this purpose.
<td style="display:none;">
You can use the nth-child CSS selector to hide a whole column:
#myTable tr > *:nth-child(2) {
display: none;
}
This works under assumption that a cell of column N (be it a th or td) is always the Nth child element of its row.
Here's a demo.
​
If you want the column number to be dynamic, you could do that using querySelectorAll or any framework presenting similar functionality, like jQuery here:
$('#myTable tr > *:nth-child(2)').hide();
Demo with jQuery
(The jQuery solution also works on legacy browsers that don't support nth-child).
you can also use:
<td style="visibility:hidden;">
or
<td style="visibility:collapse;">
The difference between them that "hidden" hides the cell but it holds the space but with "collapse" the space is not held like display:none. This is significant when hidding a whole column or row.
Kos's answer is almost right, but can have damaging side effects. This is more correct:
#myTable tr td:nth-child(1), #myTable th:nth-child(1) {
display: none;
}
CSS (Cascading Style Sheets) will cascade attributes to all of its children. This means that *:nth-child(1) will hide the first td of each tr AND hide the first element of all td children. If any of your td have things like buttons, icons, inputs, or selects, the first one will be hidden (woops!).
Even if you don't currently have things that will be hidden, image your frustration down the road if you need to add one. Don't punish your future self like that, that's going to be a pain to debug!
My answer will only hide the first td and th on all tr in #myTable keeping your other elements safe.
Bootstrap people use .hidden class on <td>.
You can also hide a column using the col element https://developer.mozilla.org/en/docs/Web/HTML/Element/col
To hide the second column in a table:
<table>
<col />
<col style="visibility:collapse"/>
<tr><td>visible</td><td>hidden</td></tr>
<tr><td>visible</td><td>hidden</td></tr>
Known issues: this won't work in Google Chrome. Please vote for the bug at https://bugs.chromium.org/p/chromium/issues/detail?id=174167
<style>
.hideFullColumn tr > .hidecol
{
display:none;
}
</style>
use .hideFullColumn in table and .hidecol in th.You don't need to add class in td individually as it will be problem because index may not be in mind of each td.
You can also do what vs dev suggests programmatically by assigning the style with Javascript by iterating through the columns and setting the td element at a specific index to have that style.
<!doctype html>
<html lang="en">
<head>
<style id="myStyleSheet">
...
</style>
var column = 3;
var styleSheet = document.getElementById("myStyleSheet").sheet;
var rule = "table tr td:nth-child("+ column +"),table th:nth-child("+ column +")
{display: none}";
styleSheet.insertRule(rule);
Here is the another solution to hide dynamically a column
define class for both th and td of the column to hide
<table>
<tr>
<th> Column 1 </th>
<th class="dynamic-hidden-col"> Column 2 </th>
<th Column 3 </th>
</tr>
<tr>
<td> Value 1 </td>
<td class="dynamic-hidden-col"> Value 2 </td>
<td> Value 3 </td>
</tr>
<td> row 2 Value 1 </td>
<td class="dynamic-hidden-col"> row 2 Value 2 </td>
<td> row 2 Value 3 </td>
<tr>
</table>
Here is the Jquery script for hide column.
$('#hide-col').click(function () {
$(".dynmic-hidden-col").hide();
});
This way the table column can be hidden dynamically.

Colspan all columns

How can I specify a td tag should span all columns (when the exact amount of columns in the table will be variable/difficult to determine when the HTML is being rendered)? w3schools mentions you can use colspan="0", but it doesn't say exactly what browsers support that value (IE 6 is in our list to support).
It appears that setting colspan to a value greater than the theoretical amount of columns you may have will work, but it will not work if you have table-layout set to fixed. Are there any disadvantages to using an automatic layout with a large number for colspan? Is there a more correct way of doing this?
Just use this:
colspan="100%"
It works on Firefox 3.6, IE 7 and Opera 11! (and I guess on others, I couldn't try)
Warning: as mentioned in the comments below this is actually the same as colspan="100". Hence, this solution will break for tables with css table-layout: fixed, or more than 100 columns.
I have IE 7.0, Firefox 3.0 and Chrome 1.0
The colspan="0" attribute in a TD is NOT spanning across all TDs in any of the above browsers.
Maybe not recommended as proper markup practice, but if you give a higher colspan value than the total possible no. of columns in other rows, then the TD would span all the columns.
This does NOT work when the table-layout CSS property is set to fixed.
Once again, this is not the perfect solution but seems to work in the above mentioned 3 browser versions when the table-layout CSS property is automatic.
If you want to make a 'title' cell that spans all columns, as header for your table, you may want to use the caption tag (http://www.w3schools.com/tags/tag_caption.asp / https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption) This element is meant for this purpose. It behaves like a div, but doesn't span the entire width of the parent of the table (like a div would do in the same position (don't try this at home!)), instead, it spans the width of the table. There are some cross-browser issues with borders and such (was acceptable for me). Anyways, you can make it look as a cell that spans all columns. Within, you can make rows by adding div-elements. I'm not sure if you can insert it in between tr-elements, but that would be a hack I guess (so not recommended). Another option would be messing around with floating divs, but that is yuck!
Do
<table>
<caption style="gimme some style!"><!-- Title of table --></caption>
<thead><!-- ... --></thead>
<tbody><!-- ... --></tbody>
</table>
Don't
<div>
<div style="float: left;/* extra styling /*"><!-- Title of table --></div>
<table>
<thead><!-- ... --></thead>
<tbody><!-- ... --></tbody>
</table>
<div style="clear: both"></div>
</div>
As a partial answer, here's a few points about colspan="0", which was mentioned in the question.
tl;dr version:
colspan="0" doesn't work in any browser whatsoever. W3Schools is wrong (as usual). HTML 4 said that colspan="0" should cause a column to span the whole table, but nobody implemented this and it was removed from the spec after HTML 4.
Some more detail and evidence:
All major browsers treat it as equivalent to colspan="1".
Here's a demo showing this; try it on any browser you like.
td {
border: 1px solid black;
}
<table>
<tr>
<td>ay</td>
<td>bee</td>
<td>see</td>
</tr>
<tr>
<td colspan="0">colspan="0"</td>
</tr>
<tr>
<td colspan="1">colspan="1"</td>
</tr>
<tr>
<td colspan="3">colspan="3"</td>
</tr>
<tr>
<td colspan="1000">colspan="1000"</td>
</tr>
</table>
The HTML 4 spec (now old and outdated, but current back when this question was asked) did indeed say that colspan="0" should be treated as spanning all columns:
The value zero ("0") means that the cell spans all columns from the current column to the last column of the column group (COLGROUP) in which the cell is defined.
However, most browsers never implemented this.
HTML 5.0 (made a candidate recommendation back in 2012), the WhatWG HTML living standard (the dominant standard today), and the latest W3 HTML 5 spec all do not contain the wording quoted from HTML 4 above, and unanimously agree that a colspan of 0 is not allowed, with this wording which appears in all three specs:
The td and th elements may have a colspan content attribute specified, whose value must be a valid non-negative integer greater than zero ...
Sources:
https://www.w3.org/TR/html50/tabular-data.html#attributes-common-to-td-and-th-elements
https://html.spec.whatwg.org/multipage/tables.html#attributes-common-to-td-and-th-elements
https://www.w3.org/TR/html53/tabular-data.html#attributes-common-to-td-and-th-elements
The following claims from the W3Schools page linked to in the question are - at least nowadays - completely false:
Only Firefox supports colspan="0", which has a special meaning ... [It] tells the browser to span the cell to the last column of the column group (colgroup)
and
Differences Between HTML 4.01 and HTML5
NONE.
If you're not already aware that W3Schools is generally held in contempt by web developers for its frequent inaccuracies, consider this a lesson in why.
For IE 6, you'll want to equal colspan to the number of columns in your table. If you have 5 columns, then you'll want: colspan="5".
The reason is that IE handles colspans differently, it uses the HTML 3.2 specification:
IE implements the HTML 3.2 definition, it sets colspan=0 as colspan=1.
The bug is well documented.
If you're using jQuery (or don't mind adding it), this will get the job done better than any of these hacks.
function getMaxColCount($table) {
var maxCol = 0;
$table.find('tr').each(function(i,o) {
var colCount = 0;
$(o).find('td:not(.maxcols),th:not(.maxcols)').each(function(i,oo) {
var cc = Number($(oo).attr('colspan'));
if (cc) {
colCount += cc;
} else {
colCount += 1;
}
});
if(colCount > maxCol) {
maxCol = colCount;
}
});
return maxCol;
}
To ease the implementation, I decorate any td/th I need adjusted with a class such as "maxCol" then I can do the following:
$('td.maxcols, th.maxcols').each(function(i,o) {
$t = $($(o).parents('table')[0]); $(o).attr('colspan', getMaxColCount($t));
});
If you find an implementation this won't work for, don't slam the answer, explain in comments and I'll update if it can be covered.
Another working but ugly solution : colspan="100", where 100 is a value larger than total columns you need to colspan.
According to the W3C, the colspan="0" option is valid only with COLGROUP tag.
Below is a concise es6 solution (similar to Rainbabba's answer but without the jQuery).
Array.from(document.querySelectorAll('[data-colspan-max]')).forEach(td => {
let table = td;
while (table && table.nodeName !== 'TABLE') table = table.parentNode;
td.colSpan = Array.from(table.querySelector('tr').children).reduce((acc, child) => acc + child.colSpan, 0);
});
html {
font-family: Verdana;
}
tr > * {
padding: 1rem;
box-shadow: 0 0 8px gray inset;
}
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
<th>Header 4</th>
<th>Header 5</th>
<th>Header 6</th>
</tr>
</thead>
<tbod><tr>
<td data-colspan-max>td will be set to full width</td>
</tr></tbod>
</table>
Simply set colspan to the number of columns in the table.
All other "shortcuts" have pitfalls.
The best thing to do is set the colspan to the correct number to begin with. If your table has 5 columns, set it to colspan="5" That is the only way that will work in all scenarios. No, it's not an outdated solution or only recommended for IE6 or anything -- that's literally the best way to handle this.
I wouldn't recommend using Javascript to solve this unless the number of columns changes during runtime.
If the number of columns is variable, then you'll need to calculate the number of columns so that you can populate the colspan. If you have a variable number of columns, whatever is generating the table should be able to be adapted to also calculate the number of columns the table has.
As other answers have mentioned, if your table is not set to table-layout: fixed, you can also just set colspan to a really large number. But I find this solution messy, and it can be a headache if you come back later and decide it should be a fixed table layout. Better just to do it correctly the first time.
A CSS solution would be ideal, but I was unable to find one, so here is a JavaScript solution: for a tr element with a given class, maximize it by selecting a full row, counting its td elements and their colSpan attributes, and just setting the widened row with el.colSpan = newcolspan;. Like so...
var headertablerows = document.getElementsByClassName('max-col-span');
[].forEach.call(headertablerows, function (headertablerow) {
var colspan = 0;
[].forEach.call(headertablerow.nextElementSibling.children, function (child) {
colspan += child.colSpan ? parseInt(child.colSpan, 10) : 1;
});
headertablerow.children[0].colSpan = colspan;
});
html {
font-family: Verdana;
}
tr > * {
padding: 1rem;
box-shadow: 0 0 8px gray inset;
}
<table>
<tr class="max-col-span">
<td>1 - max width
</td>
</tr>
<tr>
<td>2 - no colspan
</td>
<td colspan="2">3 - colspan is 2
</td>
</tr>
</table>
You may need to adjust this if you're using table headers, but this should give a proof-of-concept approach that uses 100% pure JavaScript.
Anyone else here feel that diving into JS for this seemingly minor issue seems a bit much?
PURE CSS
Boom! I have a pure CSS solution to offer you! Example is below, you just have to add a class to the row that you want to span all columns. Then the CSS will make the first <td> element span the full width and hide the remaining <td> elements. (You must use visibility:hidden; and NOT display:none; for this.)
Note: You will need at least two cells for this method to render nicely, and CSS will render best if you keep the correct quantity of <td> elements - don't remove any to make room for span element. This will help ensure the cells / rows still flow normally.
EXAMPLE
/* standard styling css */
table {
border-collapse: collapse;
}
table, tr, td {
border: 1px solid black;
}
td {
padding: 3px;
}
/* make full width class span the whole table */
.full-span {
position:relative;
}
.full-span > * {
visibility: hidden;
border:0;
}
.full-span > *:nth-child(1) {
display: block;
visibility: unset;
position:absolute;
}
<table>
<tbody>
<tr>
<td>A1</td>
<td>A2</td>
<td>A3</td>
<td>A4</td>
</tr>
<tr class="full-span">
<td>B1 long text</td>
<td>B2</td>
<td>B3</td>
<td>B4</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
<td>C3</td>
<td>C4</td>
</tr>
<tr>
<td>D1</td>
<td>D2</td>
<td>D3</td>
<td>D4</td>
</tr>
</tbody>
</table>
Bonus tip!
if you are dynamically producing your table in PHP/JS, this may clean up some of your code. Say you are looping through a 2D array to create a table: for each row that needs to span all columns you'll need to add some logic to calculate the amount of columns, add the colspan attribute, add any remaining <td> elements required to make up the full width of the table and so on.
Using my method, you can loop through all the columns and output them all, and simply include the class in the parent row.
Just want to add my experience and answer to this.
Note: It only works when you have a pre-defined table and a tr with ths, but are loading in your rows (for example via AJAX) dynamically.
In this case you can count the number of th's there are in your first header row, and use that to span the whole column.
This can be needed when you want to relay a message when no results have been found.
Something like this in jQuery, where table is your input table:
var trs = $(table).find("tr");
var numberColumns = 999;
if (trs.length === 1) {
//Assume having one row means that there is a header
var headerColumns = $(trs).find("th").length;
if (headerColumns > 0) {
numberColumns = headerColumns;
}
}
colspan="100%"
it's work also in email outlook , gmail....