Style the first <td> column of a table differently - css

If I have a table with two columns, how do I specify a padding or any other css so that it is applied just for the first column of <td>s. Also how do I style an n-th column similarly?

You could use the n-th child selector.
to target the nth element you could then use:
td:nth-child(n) {
/* your stuff here */
}
(where n starts at 1)

The :nth-child() and :nth-of-type() pseudo-classes allows you to select elements with a formula.
The syntax is :nth-child(an+b), where you replace a and b by numbers of your choice.
For instance, :nth-child(3n+1) selects the 1st, 4th, 7th etc. child.
td:nth-child(3n+1) {
/* your stuff here */
}
:nth-of-type() works the same, except that it only considers element of the given type ( in the example).
For more information about nth-child
https://developer.mozilla.org/es/docs/Web/CSS/:nth-child

If you've to support IE7, a more compatible solution is:
/* only the cells with no cell before (aka the first one) */
td {
padding-left: 20px;
}
/* only the cells with at least one cell before (aka all except the first one) */
td + td {
padding-left: 0;
}
Also works fine with li; general sibling selector ~ may be more suitable with mixed elements like a heading h1 followed by paragraphs AND a subheading and then again other paragraphs.

This should help. Its CSS3 :first-child where you should say that the first tr of the table you would like to style. http://reference.sitepoint.com/css/pseudoclass-firstchild

To select the first column of a table you can use this syntax
tr td:nth-child(1n + 2){
padding-left: 10px;
}

Related

CSS: applying class to tbody cells (in the same column) based on header class

couldn't find anything so here's my Markup:
<style>
table {
width:300px;
border-collapse:collapse;
}
th.price
{
text-align:right;
background:yellow;
}
th, td
{
border:1px solid #aaa;
}
</style>
<table>
<thead><tr><th>Item</th><th class="price">Price</th></tr></thead>
<tbody>
<tr><td>Item1</td><td>12.30</td></tr>
<tr><td>Item2</td><td>23.40</td></tr>
<tr><td>Item2</td><td>45.60</td></tr>
</tbody>
</table>
https://jsfiddle.net/2b67rw5o/
Desired output:
So I don't want to apply .price to each table cell or use :nth-child or jQuery .. would it be possible with css only?
I don’t think you can apply a class to td elements based on the class applied to a th element, in css.
You don’t want to use jQuery, but you can use vanilla javascript:
const cssClass = "price";
const th = document.getElementsByClassName(cssClass)[0];
const thead = th.parentElement;
const idx = Array.prototype.indexOf.call(thead.children, th);
const tbody = th.parentElement.getElementsByTagName("tbody")[0];
Array.prototype.forEach(tbody.getElementsByTagName("tr"), tr => {
tr.children[idx].classList.add(cssClass)
})
I don't think what you want to do is possible in CSS today. Although it was often requested, you can't travel (at least now) over parents with CSS selectors because CSS cannot pass information upwards in the DOM hierarchy. But this specific feature would be the minimum requirement to determine the index of the children in the following rows that need to be styled.
For more on that see the answer of "Is there a CSS parent selector?", which is stating "There is currently no way to select the parent of an element in CSS. (...) That said, the Selectors Level 4 Working Draft includes a :has() pseudo-class that will provide this capability."
With the currently drafted :has() you could at least build a repetitive CSS solution with a finite column count like this:
/* For a column of three columns maximum: */
/* if price is first column */
table:has(thead > th.price:first-child) tbody > td:first-child,
/* if price is second column */
table:has(thead > :first-child+th.price) tbody > :first-child+td,
/* if price is third column */
table:has(thead > :first-child+*+th.price) tbody > :first-child+*+td {
...
}
Crappy, I know... but currently the only native CSS solution in a possible foreseeable future.
But for now depending on what you need, you could also "cheat": If the background and/or border of the column should be changed you can use styling of the th header cell only (e.g. by abusing :before and :after). But text content specific changes would be quite impossible without JavaScript.

CSS: select all starting from n-th element

How can I select all child elements starting from n-th element? For example I have a div with 7 spans and I need to select all spans starting with 3-rd element, so 4,5,6,7 should be selected.
div>span:nth-child(2)~span should do the trick. The ~ General Sibling Combinator selects all following elements. The spec is at http://www.w3.org/TR/css3-selectors/#general-sibling-combinators
CSS2.1 selector
span + span + span + span {
/* matching a span that has at least 3 siblings before it */
}
CSS3 selector
span:nth-child(n+4) {
/* matching from 4th span on */
}
You can use
div:nth-child(n+3) {
// your style here
}
However, this does not specifically select elements 3-7. Instead, it excludes the first two elements. So it would also select elements 8,9, ...

Middle Child Pseudo-Class

Is there a way to use CSS selectors to get the middle child in a list of elements?
I know that there is no literal :middle-child selector, but is there another way without resorting to Javascript?
This has been working well for me:
*:not(:first-child):not(:last-child) {
...
}
You can see an example of this here: http://codepen.io/bentomas/pen/Gwqoe
The one caveat to this is that it only works in IE 9+: http://caniuse.com/#feat=css-sel3
While not elegant, if you know the upper and lower limits of the total number of elements, you could take a brute force approach to select the middle element.
For example, the following rules will select the middle element in a set of 5, 7, or 9 elements.
div:nth-child(3):nth-last-child(3) {
/* The middle element in a set of 5 is the 3rd element */
}
div:nth-child(4):nth-last-child(4) {
/* The middle element in a set of 7 is the 4th element */
}
div:nth-child(5):nth-last-child(5) {
/* The middle element in a set of 9 is the 5th element */
}
Or with Sass:
#for $i from 3 through 5 {
div:nth-child(#{$i}):nth-last-child(#{$i}) {
/* The middle element */
}
}
You can use the "not first and not last" approach, like so:
CSS
li:not(:first-child):not(:last-child) {
color:red;
}
HTML
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Check the JsFiddle
If you want to apply a style to all elements that are neither first children nor last children, you could use :not(:first-child), apply the style, and then use :last-child to 'take the style away' from the last element. But you'd have to think about what happens when there are less than 3 elements.
I've encountered the need to target the middle child on several occasions, and I've taken to using this sass mixin I wrote after referencing many similar questions, and their respective answers.
// Generate a reasonable number rules limited by $n.
#mixin middle-child($n) {
// There is no middle for nChildren less than 3,
// so lets just start at 3.
#for $i from 3 to $n {
// Find the middle, bias right for odd numbers.
$mid: math.ceil(math.div($i, 2));
// Select only those sets of children that number $i.
&:first-child:nth-last-child(#{$i}) {
// Select the middle child of that set.
~ :nth-child(#{$mid}) {
#content; // Apply your styles.
}
}
}
}
Usage:
.navigation {
background-color: #ba0020;
.nav-item {
color: white;
#include middle-child( 8 ) {
font-weight: 900;
}
}
}
Have you tried :nth-child(#) ?
Depending on which one you want to select you just replace # with the number.
Javascript is the only way to do this client side.

CSS3: Reset alternate table row coloring after a certain class of tr

Here's my fiddle.
http://jsfiddle.net/cnLDF/
I want every .content row after each .heading row to start with gray, in this case, "content 5".
How do I do it by modifying the CSS only.
Using the adjacent sibling selector (i used red color for demo purposes):
table tr.heading + tr.content {
background: #f00;
}
But note that the nth-child(even) will win, then you will colour only the first .content, preceeded by an .header, that is odd (and not even).
Demo: http://jsfiddle.net/cnLDF/1/
EDIT:
I've tried a bit, and I don't think it's possible with pure CSS (but i'll be happy to be proven wrong): pseudo-elements will always refer to all tr elements in the table (with odd and even), and the last declaration will override the previous... the only way with CSS only imho is to create a static declaration for every case with adjacent selector after every heading, that is doable only if you have a small, known, fixed number of content for every heading (let's say 5, or 10...), like this:
table tr.heading + tr.content > td {/* stuff */ }
table tr.heading + tr.content + tr.content > td {/* stuff */ }
table tr.heading + tr.content + tr.content + tr.content > td {/* stuff */ }
/* and so on... */
If instead you could handle the input, you could easily calculate the output serverside, applying "odd" and "even" classes to trs, and coloring them accordingly.

Is there such a thing as an "all inclusive sibling" CSS selector?

My HTML:
<p>Doggies</p>
<p class="green_guys">Froggies</p>
<p>Cupcakes</p>
<p>Piggies</p>
An all inclusive sibling selector (as I wish it to be), when used to select green_guys' siblings, would select the doggies cupcakes and piggies.
Other Selectors:
The + selector (a.k.a. adjacent sibling selector) would only select the cupcakes:
.green_guys + p {
/* selects the <p> element that immediately follows .green_guys */
}
The ~ selector (a.k.a. general sibling selector) would only select the cupcakes, and piggies:
.green_guys ~ p {
/* selects all <p> elements that follow .green_guys */
}
There is no sibling combinator that looks backward or around, only the adjacent and general sibling combinators that look forward.
The best you can do is determine a way to limit selection only to these p elements with the same parent, and then select the p children that are :not(.green_guys). If the parent element has an ID of #parent, for example, you can use this selector:
#parent > p:not(.green_guys) {
/* selects all <p> children of #parent that are not .green_guys */
}
However the above will still match your p elements even if none of them have the class. It is currently not possible to select the siblings of an element only given the existence of said element (which is the purpose of a sibling combinator — to establish a relationship between two sibling elements).
Selectors 4's :has() will hopefully rectify this without the need for a preceding-sibling combinator, resulting in the following solution:
p:has(~ .green_guys), .green_guys ~ p {
/* selects all <p> elements that are siblings of .green_guys */
}
This will not match anything if none of the children of the parent element have the class.
Not that I am aware of. There isn't a siblings selector either.
This might work, though:
#parent_of_green_guys > p:not(.green_guys) {
foo: bar;
}
Or if you aren't looking for ps with class attributes:
#parent_of_green_guys > p:not([class]) {
foo: bar;
}
My scenario was a little different but I wanted to select siblings of an input element to display one while it was active and another if it was left invalid.
My html was like this and I was unable to select the invalid text.
<input name="importantAnswer">
<div class="help-text"></div>
<div class="invalid-text"></div>
I was able to get around it by embedding the siblings in an adjacent one and using child selectors on that.
<input name="importantAnswer">
<div class="messages">
<div class="help-text"></div>
<div class="invalid-text"></div>
</div>
.help-text, .invalid-text {
visibility:hidden;
}
.input:active +.messages > .help-text {
visibility:visible;
}
.input.invalid:visited +.messages > .invalid-text {
visibility:visible;
}
And it worked.
I actually found 3 ways to do this:
Solution 1
.parent > p:not(.green_guys) {
text-decoration: line-through; /* or whatever you like */
}
Demo:
https://jsbin.com/cafipun/edit?html,css,output
PROS: quick and easy.
CONS: you need to know the parent selector (so that's not a super portable solution).
Solution 2
p ~ p:not(.green_guys),
p:first-child:not(.green_guys) {
text-decoration: line-through; /* or whatever you like */
}
Demo:
https://jsbin.com/seripuditu/edit?html,css,output
PROS: there is no need to know the parent selector (it can be very good to be used in generic cases).
CONS: it risks to be too generic (be careful, for example, if you have other p around your HTML!).
Solution 3
Small variant of the Solution 2 (to avoid the CONS). In this case you specify the sibling selector to get a more specific context.
p.siblings ~ p:not(.green_guys),
p.siblings:first-child:not(.green_guys) {
text-decoration: line-through; /* or whatever you like */
}
Demo:
https://jsbin.com/hakasek/edit?html,css,output
PROS: it is a portable solution, there is no need to know the parent selector (it can be very good in generic cases) and there is no worry to have conflict with other elements.
CONS: all siblings have to be well defined (with a class or an attribute for example).

Resources