Can I combine pseudo-classes in CSS like this? - css

HTML:
<table>
<tr class="not-counted"><th>Heading 1</th></tr>
<tr><td>key1</td><td>val1</td></tr>
<tr><td>key2</td><td>val2</td></tr>
<tr class="not-counted"><th>Heading 2</th></tr>
<tr><td>key3</td><td>val3</td></tr>
</table>​
CSS style:
table tr:not(.not-counted):nth-child(even) td {
background-color: gray;
}​
Demo: http://jsfiddle.net/MartyIX/fdtpL/
I hoped that TR containing key3 would have grey background too but it does not work. How to write the CSS properly?
Thanks!

You want to style in CSS a table with zebra rows with an unknown number of rows not styled (or hidden, same result), these unstyled rows being at any position in the table.
Each remaining row to be styled is preceded by an unknown number of unstyled rows at odd position and an unknown number of unstyled rows at even position in whatever order.
Your particular need isn't stylable in CSS2.1 or CSS3, unless you add a constraint.
By example, if you know how much unstyled rows you could encounter, than the 2 fiddles in my following twit will do the trick: https://twitter.com/#!/PhilippeVay/statuses/166243438436687873 This is CSS from hell, don't ever do that in production! As briefly stated, jQuery/Sizzle and its pseudo :visible would be far superior. Or even better, add a class server-side to each row you want to style.
Other fiddle with your example: http://jsfiddle.net/yBKqy/
You can see that it works till the row next to your second unstyled row. The remaining rows below are both preceded by an odd unstyled row and an even unstyled row; the rule that apply will be the last one declared. AFAIK no way to apply one or another in a meaningful way. If you add weight to the first selector, it'll always apply. If you don't the last one will always apply.
If you know how much rows can follow an unstyled row before there's another unstyled row or the end of the table, here's another fiddle: http://jsfiddle.net/yBKqy/3/
This particular example works with no more than 4 rows in a row but not 6. You can make it works with 6 but it'd fail with 7, etc

I solved the problem with the help of dummy lines:
HTML
<table>
<tr><th>Heading 1</th></tr>
<tr style="display:none;"><th></th></tr> <!-- dummy line -->
<tr><td>key1</td><td>val1</td></tr>
<tr><td>key2</td><td>val2</td></tr>
<tr><th>Heading 2</th></tr>
<tr style="display:none;"><th></th></tr> <!-- dummy line -->
<tr><td>key3</td><td>val3</td></tr>
</table>​
CSS
table tr:nth-child(even) td {
background-color: gray;
}​
Demo
http://jsfiddle.net/MartyIX/fdtpL/3/
I'm not really proud of it but I've lost too much time with that.

Related

CSS selector for hideous table-driven markup

JSFiddle: https://jsfiddle.net/dc9wdwem/
I inherited a legacy application that some clients are still using and expecting upgrades for. One recent upgrade "broke" the existing CSS and the easiest way to resolve it is to "un-break" just one little table.
The markup is nested table upon nested table. But for the sake of stripping down to the bare essentials, here's the barest version of where to find my table.
<div id="someId">
<table>
<tr>
<td>
<table>
<tr>
<td>
<table> <!-- not this table --> </table>
</td>
<td>
<table> <!-- THIS ONE!! --> </table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
There are other tables and rows and cells scattered throughout, but this structure gets you there.
Using the "direct descendant" symbol is tricky because the tables are descended within rows and cells as well as other tables. So table>table>table isn't going to do it. But then if you go with a general descendent selector, you end up selecting too many things table table table will get you a whole bunch of tables. Here's the closest I got so far:
#someId>table table td:nth-child(2) table {
background-color: red;
}
I would normally be glad to add even more > selectors; however, I believe the browsers themselves are filling in tbody elements and so forth and I don't know that I can reasonably predict that the proper structure will always be intact. The above selector is selecting more tables than the one I'm trying to isolate.
None of the nested tables have IDs or classes, and nor do I have the opportunity to add them in. The upgrade process does not upgrade the customer's markup, which they may have themselves partially customized over time.
Anybody have any CSS selector magic that will work, assuming the above markup alongside browser-filled elements like tbody?
This will work for the specific HTML in your fiddle:
#someId>table table:nth-of-type(1) td:nth-of-type(2) table {
background-color: red;
}
Obviously, if the HTML changes in pretty much any way, this is probably not going to work.
You missed a Table in your css.
try:
div#someId > table table table td:nth-child(2) > table
https://jsfiddle.net/ba52Lwkg/
#someId > table table:first-of-type td + td > table
this should work.
https://jsfiddle.net/dc9wdwem/

What's the difference between "." and "#" in CSS and how to choose to use?

I'm learning in CSS, I am really confused when to use .(dot) and when to use # in CSS file. Sometimes I really wondered which one I should use.
#You are .Human
While there are many humans, there is only one you. As such, . is for classes, which can appear over and over in a document. # is for IDs, which are unique to a document.
<div class="firstname" id="personA">
<p class="lastname">Sampson</p>
</div>
<div class="firstname" id="personB">
<p class="lastname">Sampson</p>
</div>
Note the unique identifier for both div, personA and personB. However both elements have classes in common, such as .firstname, and .lastname.
Professional Examples
You can see how these are used out in the wild by looking at tools like Modernizr. This feature-detection tool assists you by adding classes to the <html> element that inform you as to what the device or browser is capable of:
<html lang="en" dir="ltr"
id="modernizrcom"
class="js no-touch postmessage history multiplebgs boxshadow...">
Here we see the one unique value for the <html> element, #modernizrcom. Following, a series of classes that give more general info about the element. This is a clear example of how an element can have only one id, but many classes.
Careful with those IDs!
Because these values are completely unique, they can cause you to paint yourself into a corner at times. It's worth reading Disallow IDs in Selectors to know more about the potential issues with using IDs in your selectors.
The # is used for the id of an element and . is used for classes of an element. In a HTML document, an id is unique (there should only be one element with that id) while classes can occur multiple times.
<div id="content" class="shade light">
</div>
You can now do:
#content { border: solid 1px black; }
to add styling to that particular div element. But you can also do:
.light { background-color: #eeeeee; }
The difference is that the latter will apply that background color to all elements with that class (i.e., all elements with the class light while the first CSS statement will only add styling to the element with the id content).
a dot (.) represents a class, a hash (#) represents an id.
There is more to it, but this is the gist:
An id (#myID) should be used when you only intend to use that selector once
A class (.myClass) should be used to create a reusable piece of styling code (e.g. to make text blue)
. is represent class
# is represent ID(but used only once in a page)
always the id is having the first priority in the race.
ex:
in the style
.alignmeleft{float:left;}
#alignmeright{float:right;}
in the html:
<div class="alignmeleft" id="alignmeright">
<!--div content-->
</div>
OUTPUT
THE DIV WILL ALIGNED RIGHSIDE

strange IE8 css issue

I have a header row which has this structure:
<th...
<a...
<span...
{text}
If you look at the attachement, you will notice that all the headers with this structure are aligned.
Well, when a specific header is clicked for "sorted" status, the structure will be like:
<th...
<a...
<span...
<table>
<tbody>
<tr>
<td>
{text}
</td>
<td>
<div> //with a background image
</td>
</tr>
</tbody>
</table>
Well, in IE8 this sorted column is no longer aligned (see the screenshot please).
I've tried a lot to put some css style (position:relative, etc) to the table inside the span to fix the alignment in IE8 but I failed..
Is here any css guru which can suggest a fix?
Please note that I can NOT change this structure (its some generated code from ICEfaces library) but I can apply css attributes (if I know where...).
Also, there is no css difference (some specific important style) to the sorted column applied. Just plain table inside that span.
Thanks.
Check the vertical-align property, maybe. Here, judging by the screencap, it seems to be in default mode, 'baseline'. (I'm not sure it will do much, though)
Try :
th.stuff {
vertical-align:top;
}
or :
th.stuff {
vertical-align:middle;
}
Also you could make all th slightly higher and gain somme padding to align the content. I think the problem, overall; commes from the select that appears in the th, inside the table.
You can use IE specific style sheets. They are known as conditional style sheets.
http://css-tricks.com/132-how-to-create-an-ie-only-stylesheet/
The idea of course would be to change the CSS for that element for IE only (because it does work already with other browsers).

Is there a way to use wildcards in css id tag

assuming i have few items with similar ids:
<input class="a" id="id_1"/>
<input class="a" id="id_2"/>
i would like to set in my css file something like:
#id_*{width = 100%;}
is there a way i can do that?
i've tried something like:
input[id^='id_']{width:200px;}
but that didnt worked out......
And its need to work on IE :(
EDIT: nedd to work on IE8....
EDIT:
<input tabIndex="1690" class="form" id="cust_1_NUM_OBJ_5-00461" dataFld="cust_1_NUM_OBJ_5-00461" dataSrc="#FIELDVALUES" style="text-align: right; height: 20px;" onkeypress="validateNumberChar(this)" onfocus="resetGFocusField('cust_1_NUM_OBJ_5-00461');" onblur="validateChangedNumber(this);" onbeforedeactivate="onbeforedeactivateLookup(this);" type="text" size="20" maxLength="55" datatype="number" numbertype="24,6" valueFieldID="null" tabStop="true" value="1"/>
and CSS:
input[id^='cust_1_NUM_OBJ_5-0046']{width:200px;}
input[id^='id_']{width:200px;} should work. It certainly does in this fiddle:
http://jsfiddle.net/jYZnX/
EDIT: Also, to show that it doesn't pick an input without an id beginning 'id_':
http://jsfiddle.net/jYZnX/1/
EDIT 2: As your Document Mode seems to be set to Quirks this will cause issues with the css selector. Set your doc type correctly, eg using <!DOCTYPE HTML>. This will need access to the original code for the web pages though, so without that you will be in a spot of bother.
The selector you used (^), works correctly in IE:
input[id^='id'] {
background: red;
}
And here is the result:
IE7
IE8
IE9
IE10
As I saw in your pictures, your IE is rendering your page with Quirks Mode.
Maybe you have no doctype or wrong doctype at your page. Make your doctype valid as below:
<!doctype html>
My answer is quite general and never directly related to the question because this is already very old and so far solved by other answers on this page.
The first part of this answer is dry theory which is useful to understand the options.
The second part is an example for usage of this theory.
1) ATTRIBUTE SELCTORS
Substring matching attribute selectors:
[att^=val]
Represents an element with the att attribute whose value begins with the prefix "val". If "val" is the empty string then the selector does not represent anything.
[att$=val]
Represents an element with the att attribute whose value ends with the suffix "val". If "val" is the empty string then the selector does not represent anything.
[att*=val]
Represents an element with the att attribute whose value contains at least one instance of the substring "val". If "val" is the empty string then the selector does not represent anything.
Additionally there are still more selectors, in the specification they are sorted in the chapter Attribute presence and value selectors:
[att]
Represents an element with the att attribute, whatever the value of the attribute.
[att=val]
Represents an element with the att attribute whose value is exactly "val".
[att~=val]
Represents an element with the att attribute whose value is a whitespace-separated list of words, one of which is exactly "val". If "val" contains whitespace, it will never represent anything (since the words are separated by spaces). Also if "val" is the empty string, it will never represent anything.
[att|=val]
Represents an element with the att attribute, its value either being exactly "val" or beginning with "val" immediately followed by "-" (U+002D).
2) EXAMPLE HOW TO SELECT SEVERAL THINGS ON A PAGE DEPENDING ON AN EVENT
Wildcards are especially then useful when an event is triggered like that a page is visited with a special hash-tag. For a completely static page in contrast they are also useful but still could be noted different, even it would be more CSS-code.
Assume a page is visited with the hash-tag action, so the URL would look like this:
https://example.com/index.html#action
While only one id is triggered like that we can use it to note a whole stack of related actions in CSS, we just have to enclose the whole area where something shall happen in an element with the id action:
/* all div-elements which are direct child of element with class `wrapper` are hidden: */
.wrapper>div {
display: none;
}
/* following line addresses all elements inside element with the id "action"
where the id is starting with "action_". This is only triggered when the
URL with hashtag "action" is called, because of usage of ":target":
*/
#action:target [id^="action_"] {
display: block;
}
/* following line addresses all elements inside element with the id "amother-action"
where the class is "another-action". This is only triggered when the
URL with hashtag "another-action" is called, because of usage of ":target".
This example shows that we never need ids but can use classes too:
*/
#another-action:target .another-action {
display: block;
}
<div id="action">
<div id="another-action">
<div class="wrapper">
<!-- this small menu is always shown as it's an unordered list and no div: -->
<ul>
<li>No Action / Reset</li>
<li>Action</li>
<li>Another Action</li>
</ul>
<!-- The following div-elements are by default hidden and
only shown when some event is triggered: -->
<div id="action_1" class="another-action">
<!-- this is on both actions shown as the div has an id starting
with "action" and also a class "another-action" -->
Hello
</div>
<div id="action_2">
<!-- this is above only triggered by the CSS-rule
#action:target [id^="action_"] -->
World!
</div>
<div class="another-action">
<!-- This is above only triggered by the CSS-rule
#another-action:target .another-action -->
Everybody!
</div>
</div>
</div>
</div>
The different results are these:
When the page is called without any hash, only the menu is shown:
Action
Another Action
When the page is called with the hash action, below the menu can be seen:
Hello
World!
When the page is called with the hash another-action, below the menu can be seen this instead:
Hello
Everybody!
Like this we can mix much content where each division is only shown in special cases.
Mixing several ids and classes does only work if the elements with the ids are enclosing the elements with content and select-able properties. In my example above you can see that everything in HTML is written between <div id="action"><div id="another-action"> and </div></div>, like this every used event can optionally trigger everything in the content between.
Naturally it's possible by CSS to use this method for other effects too. Hiding or showing the elements is only a simple example but you could change colors, start CSS-animations and do many other things by CSS.
Keep care that you don't publish any confidential things in any of those elements, because this CSS-solution is no security but only for distinguishing cases for visual display.
Any things you hide or show like this are always visible in the HTML-source.
Given a three-column table with 200 rows and each row having an individual id like this row:
<tr id="row_177">
<td><a class="btn" href="..">Link1</a></td>
<td>Name of PDF File</td>
<td><select class="pdf_sel">
<option value=""> ---- </option>
<option>Crowell, Thomas</option>
</select>
</td>
</tr>
and given that you want to vertically center the content in each td, then the following css wildcard will cause the content of each td to be centered vertically** (I'm sure you could also use this to adjust width):
tr[id^='row_'] > td {
vertical-align:middle
}
** One caveat - the third column in the table contains a Select in each td. While the anchor button in the first column and the text anchor in the second column are centered vertically in each td by using the above css, the Select in the third column does not respond to this css for some reason - but there is a fix. The following css will cause the Select elements to be properly centered vertically:
tr[id^='pdfrow_'] > td > select {
margin-top:5px;
margin-bottom:5px
}
That is precisely what classes are for. What you want is:
.a { width: 100% }

What is the proper CSS way to implement right-aligned text on table columns?

To my surprise I just found out that applying text-alignment to a table column is fairly bad supported in current browsers. Neither Firefox 3.5.2, Safari 4.0.3 or IE8 shows the "amount" column below as right aligned.
HTML:
<table class="full_width">
<caption>Listing employees of department X</caption>
<col></col>
<col></col>
<col></col>
<col class="amount" width="180"></col>
<thead>
<tr>
<th>Name</th>
<th>Phone number</th>
<th>Email</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>+45 2373 6220</td>
<td>john#doe.com</td>
<td>20000</td>
</tr>
</tbody>
</table>
CSS
.amount{
text-align: right;
}
Why isn't this working? Also I tried (via firebug) to turn off Firefox' native rule that left-aligns TD elements, but that didn't work either.
I can see that setting background color rule in the amount css class actually works. So I know that the .amount class is applied to all columns:
CSS
.amount{
text-align: right;
background-color: aqua;
}
The CSS 2 spec apparently says that only four attributes are supported by col element -- see Why is styling table columns not allowed?
Criteria for selecting the best solution: must be supported fairly cross-browser (not necessarily in IE6 where I could live with using jquery or a conditional comment to include a specific solution). Also, I expect to apply multiple classes multiple different columns (ie. class="amount before_tax")
I'd hate to set classes on the relevant td in each row. What are my options?
I'd hate to set classes on the
relevant td in each row. What are my
options?
That would be it: class on each td.
If you don't want to add the class to each cell in a column manually, your only other option is to use javascript to do it.
With jQuery:
$("table tbody tr td:eq(3)").addClass("amount");
You can always set a class on on the last element in a row:
.full_width td:last-child {
text-align: right;
}
you have to set the class on the td elements. I think that's the only way.
Your answers got me thinking about creating a JQuery script that parses COL elements. Then it should find each row matching the corresponding COL and apply the COL class to each element like so:
enter code here$("table tbody tr td:eq(3)").addClass("amount");
But only do it, (as a performance improvement), if the class definition contains a text-align in it.
Of course, a full complex implementation of colspan and COLGROUP elements will be overkill and most likely not supported.
Any thoughts on that idea?

Resources