advanced :hover deeper nested - css

I don't know exactly how I can describe this? I think its better if you look at the jsfiddle I have made..
As you can see there is a hover on some TR elements and if the TD already has another bgcoler it has to change to an alternative bgcolor..
It works fine in the first 3 rows, but if there is nested a new table deeper in the DOM the green TD's in the new table does always have the :hover class
jsfiddle
http://jsfiddle.net/VvZuV/1/

Change this:
tr:hover td.green, tr.deep:hover td.green {
background:#7bcf81;
}
To this:
tr:hover > td.green, tr.deep:hover > td.green {
background:#7bcf81;
}
No new class needed.
http://jsfiddle.net/rCztp/
Explanation
As soon as you hovered over the <tr> that contained the <table>, all children, grand-children, and etc, were affected by your css rule. Using > means that only children will be affected.

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.

How to apply last th in table display none?

I have a problem with table th, I can not set display none to the last th.
Here is my code:
#content-area-job-details #site-content-job-details .entry-content table.job-table tr th:last-of-type{
display:none;
}
when I use this code it set display to none for all th. I want only last th display none.
You can see my problem at:
http://westecmedia.com/?page_id=974
Help me please
This doesn’t work that way. :last-child or :last-of-type are always relative to the parent container. So in case of a table, that’s the tr element. If you match all tr elements in the table, and then get the last th for each, then you are matching every last th in each of those rows. So in your case, essentially all ths.
You would need to have a way to select that one tr which you are interested in, but other than maybe :nth-last-child(2), there is not really a good way to get that one. You should add an actual class to it.
Note that just hiding the th will not give you the desired result though. Table cells are always table cells, and unless you make them take more than a single cell, they will only ever occupy a single cell. So in your case, if you hide or remove that one th, the following td will not fill the whole row. It will only fit that very small cell where the th was previously located. You would have to add colspan="2" to the td in the markup to fix that.
You should use javascript to do what you need...
(function(window) {
'use strict';
function hideLastTh() {
var lastElement;
try {
lastElement = window
.document
.querySelector('.job_info')
.parentElement
.parentElement
.querySelector('th[scope="row"]')
;
lastElement
.classList
.add('hidden')
;
} catch(e) {
console.error('hideLastTh:ERROR', e);
}
}
return window.document.addEventListener('DOMContentLoaded', hideLastTh);
})(window);
I can see that your site uses jQuery. If you can add jQuery code, just add these two lines:
$("th:last").hide();
$("th:last").siblings("td").attr("colspan","2");

Styling 'first-line' inner elements

I'm attempting to put CSS styles on the list items in the first line of a list but it seems that neither Chrome, Firefox, nor Safari will accept the style.
ul:first-line > li {
display: inline;
/* my styles here */
}
Have I overlooked the way in which I'm specifying the style, is this an oversight in CSS implementation or a deliberate CSS specification? If it is the latter, is there a good rationale behind this?
JSFiddle: http://jsfiddle.net/e3zzg/
Edit:
Please note, it seems pretty definitive that this can currently not be achieved using CSS alone but from a research standpoint and for posterity, I'm curious as to why this is. If you read the W3C CSS specification on the firstline pseudo-element there doesn't seem to be any mention of inner elements. Thanks to everyone trying to provide alternate solutions, but unless there actually is a CSS solution, the question here is 'why', not 'how' or 'is it possible'.
Here's "Why" What You Want to Do Cannot Be Done
The selectors 3 spec is a little more up to date. The following is taken from that.
The "why" is because the :first-letter is pseudo-element, that is, a "fake" or "false" element. It is producing a "fictional tag sequence", which is not recognizable in relation to other real elements. So your...
ul:first-line > li
...suffers from the same issues as this selector string...
ul:before + li
...where the combinator (whether > or +) is only looking at the "element" not the "pseudo-element" for selection. The second string does not target the "first" li of the ul that is following a :before pseudo-element. If it were to work at all, it would target an li that follows the ul in the html sequence (which, of course, there would never be one in a valid html layout).
However, a selector string similar to the second one above would not work anyway, because in actuality, the form of the above strings is not valid, as confirmed by the statement in the specifications that says:
Only one pseudo-element may appear per selector, and if present it
must appear after the sequence of simple selectors that represents the
subjects of the selector.
In other words, a pseudo-element can only be positioned dead last in the selector sequence, because it must be the target of the properties being assigned by that selector. Non valid forms apparently are simply ignored just like any invalid selector would be.
I think you would be better off with:
ul > li:first-child
:first-line is only useful for text elements
The only option to make a class apart for the second line is adding through Javascript a concrete className to them and setting the background for them. To get the current line you should iterate the elements and compare it's distance to the list top and it's previous siblings. I made a jQuery example so you can get the idea: http://jsfiddle.net/JmqxM/
$("ul.numerize-lines").each(function () {
var list = $(this);
var currentDistance = 0;
var currentLine = 0;
list.find("li").each(function () {
var item = $(this);
var offset = .offset();
var topDistance = offset.top;
if (topDistance > currentDistance) {
currentDistance = topDistance;
currentLine += 1;
}
item.addClass("line-" + currentLine);
});
});
and the css:
ul li.line-2{
background-color: #FFF;
}
Pretty sure the :first-line should be applied to the element itself that contains the text (rather than the parent, as you have).
ul > li:first-line { /*style*/ }
Or if your list items contain tags or something else like that...
ul > li p:first-line { /*style*/ }

css pseudo class, hover on one element changes properties in different element

I was wondering how I could set up css pseudo classes, specifically hover so when I hover over an element, like a div with an id, the properties of a different div with an id get changed?
so normally it would be this:
#3dstack:hover {
listed properties
}
I'm not sure what the change would be to have it hover on div with the id 3dstack and have it change another div.
I do not think that is possible unless the element you want to change the properties of is a descendent or a sibling of the hovered element, in which case you can do:
#myElement:hover #myElementDescendent {
background-color: blue;
}
/*or*/
#myElement:hover + #myElementSibling {
background-color: blue;
}
Of course you can always use jquery to do this:
$("#anelement").hover(
function() {
$("otherelement").css("background-color", "blue");
});
See the differences here
This is not possible with CSS alone. You'll have to use a JavaScript event handler. For example, with jQuery's hover:
​$('#3dstack').hover(function() {
$('#otherID').toggleClass('properties');
});​​​​​​​
DEMO
Visually you can do this using LESS, but under the hood it's actually using JavaScript.

How to reference a div with class="name1 name2"?

I'm working on some CSS from a tutorial, a div has this class:
<div class="related products">
How can I reference it in the stylesheet?
The div actually has two classes, related and products. You can reference it in your stylesheet with either .related or .products, and it will pick up the styles from both of those rules. For example, with the following CSS, the text in the div in your question would appear red with font size 12:
.related { color:#ff0000 }
.products { font-size:12px }
If you want to select elements with both classes, use .related.products in your stylesheet. For example, add the following to the above example:
.related.products { font-weight:bold }
And the text in your div will receive all three rules, because it matches all 3 selectors. Here's a working example.
div.related.products is the general method
You reference it by div.related.products which literaly translates to "a div with class of related and class of products".
Or, you could reference it by using either class names, since it will catch both.
jsFiddle Example.
In the css, just put the name class of the div by doing this:
.related products {
/*styling to go here*/
}
Now any styling within the related products class will be applied to that div.

Resources