I have a table, with a header row and numerous data rows. I have a checkbox in the first column. In the th cell, I would like to add a top and bottom margin, on the td cells, I don't want this.
I have LESS(css) that is the same for both the th and td elements with class .col-checkbox, as well as a label element in both cells with shared css. I'd like to add the margin top/bottom to the label if it is in the th cell.
.html file
<table>
<tr>
<th class="col-checkbox">
<div>Column Label</div>
<label class="custom-checkbox">
<input type="checkbox" />
<span class="checkbox"></span>
</label>
</th>
<th>
Unimportant, there are more columns as well
</th>
</tr>
<tr>
<td class="col-checkbox">
<label class="custom-checkbox">
<input type="checkbox" />
<span class="checkbox"></span>
</label>
</td>
<td>
Unimportant, there are more columns as well
</td>
</tr>
</table>
.less file
.col-checkbox {
width: 30px;
// more css here
label.custom-checkbox {
height: 24px;
// more css here
// I know I can do the following, but I'd like to not have to add
// more classes if I can someone make this dependent on whether it
// is in the th or td element
//&.header {
// margin: 6px auto;
//}
//
//&.data {
// margin: 0 auto;
//}
}
}
I know I can make it work the way I have it above, but I was curious if I can do it just by referencing the td and th elements without duplicating the other css. I don't think so, but I figured I'd ask anyway.
It looks like you are already familiar with the & operator. Well it doesn't have to go before the selector. Instead, you can use it after the selector, such as th&, to get what you want.
So this:
.col-checkbox {
width: 30px;
// more css here
label.custom-checkbox {
height: 24px;
// more css here
}
th& {
margin: 10px 0;
}
}
Outputs this:
.col-checkbox {
width: 30px;
}
.col-checkbox label.custom-checkbox {
height: 24px;
}
th.col-checkbox {
margin: 10px 0;
}
However, a word of caution that this pattern may not work as you expect if you have more than one level of nesting.
Consider this code:
.col-checkbox {
width: 30px;
// more css here
label.custom-checkbox {
height: 24px;
// more css here
.checkbox& {
color: navy;
}
}
}
You may expect to get this out of it:
.col-checkbox {
width: 30px;
}
.col-checkbox label.custom-checkbox {
height: 24px;
}
.col-checkbox label.custom-checkbox.checkbox {
color: navy;
}
But in reality you'll get this:
.col-checkbox {
width: 30px;
}
.col-checkbox label.custom-checkbox {
height: 24px;
}
.checkbox.col-checkbox label.custom-checkbox {
color: navy;
}
Related
I have referred to many options but still I am not able to apply CSS to my parent container. My table structure is like:
<td>
<div id="div1">
<div id="div2" class="colorMe"></div>
</div>
</td>
Now according to above structure if div2 has class colorMe then I want to color the entire td background in yellow.
I have used CSS like this but not working:
td > div> div.colorMe {
background-color:yellow;
}
Can you please tell me how I can color my td using css?
There is currently no possibility to apply CSS Rules to a parent element. There is in fact the :has Pseudoclass, which is exactly for this kind of issues, but at the moment (Nov 2017) it is not supported by any browser. The only way to achieve this would be with Javascript.
I know that you mentioned only using css but adding some javascript event to change a class is a very well documented approach. There are dozens of examples online and including the the script in your file takes no extra work if you use vanilla.
Here is a small example of changing a parent div's color on a click event
var box2 = document.querySelector('.color2');
box2.addEventListener("click", function() {
this.parentNode.style.backgroundColor = "white";
});
div {
width: 100px;
height: 100px;
border: 2px solid black;
}
.color1 {
background-color: red;
}
.color2 {
background-color: rebeccapurple;
width: 50px;
height: 20px;
}
<div class="color1">
<div class="color2"></div>
</div>
You can kind of emulate the behavior you need with the following trick:
td {
position: relative; /* make the cell a container for positioned children */
}
.colorMe::before { /* cover this container with colored pseudo element */
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
background-color:yellow;
z-index: -1;
}
table { /* just to make the example prettier :) */
width: 100%;
height: 100px;
table-layout: fixed;
}
<table>
<tr>
<td>
Just a TD
</td>
<td>
<div id="div1">
<div id="div2" class="colorMe"></div>
</div>
</td>
<td>
Just a TD again
</td>
</tr>
</table>
It won't work, however, if you need to position something absolutely from the .colorMe element itself.
For example, in this simulated rendering, the orange background indicates the extents of the enclosing span or div element that just encloses all the contained text:
If that's too much to hope for, then a second best would be something like this:
In this second case the locations of the top and bottom edges coincide with the text's baseline and mean line.
At the absolute very least, I'd love to learn how to reliably line up the bottom of a span or div so that it is perfectly flush against the text's baseline. Even this seemingly straightforward task is beyond my reach. (My success rate is about 50%, and AFAICT entirely random.)
Below I show my best attempts so far. My results are terrible for the most part. It is true that for one font I get pretty close to the second case shown above, but I suspect this is just a lucky coincidence, judging by how poorly the same CSS fares with other fonts.
Code snippet below (or jsFiddle). Click on Full Page for best results.
* { vertical-align: baseline !important; }
#root { padding: 20px; }
td { padding: 0px; }
.monospace { font-family: monospace; }
.proportional { font-family: tangerine; }
.ground { padding: 10px; }
.ground > * { margin: 10px; }
.ground > * { font-size: 50px; }
.ground > * { background: orange; }
.ground > * { display: inline-block; }
.tweak-heights
.ground * { height: 1ex; }
.tweak-heights
.ground * { line-height: 0; }
.tweak-heights
.ground > * { margin: 20px 10px; }
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Tangerine">
<div id="root">
<div style="display: block; width: 100%; text-align: right;"><div style="display: inline-block; margin: 0 50px 0 0;">(Click on FULL PAGE for best results.)</div></div>
<table>
<tr><td>
<div class="ground">
<span class="q monospace">Smallest SPAN 0123456789</span><br/>
<span class="q proportional">Smallest SPAN 0123456789</span><br/>
</td></tr>
<tr><td class="tweak-heights">
<div class="ground">
<span class="q monospace">Smallest SPAN 0123456789</span><br/>
<span class="q proportional">Smallest SPAN 0123456789</span><br/>
</td></tr>
</table>
</div>
I have a table with n rows. On these n rows I need to set some CSS style, following this rules:
the CSS should apply only on odd rows
the CSS should NOT apply on the first and the last row (or on those rows with .excludeme class)
the CSS should apply only on visible rows
HTML
<table>
<tr class="excludeme"><td>first</td></tr>
<tr><td>Hello</td></tr>
<tr><td>Hello</td></tr>
<tr class="showhide"><td>show/hide</td></tr>
<tr><td>Hello</td></tr>
<tr><td>Hello</td></tr>
<tr><td>Hello</td></tr>
<tr><td>Hello</td></tr>
<tr class="showhide"><td>show/hide</td></tr>
<tr class="showhide"><td>show/hide</td></tr>
<tr><td>Hello</td></tr>
<tr class="excludeme"><td>last</td></tr>
</table>
CSS
.showhide{
display: none;
}
table tr:nth-child(odd):not(.excludeme){
background: orange;
}
JS
//--- #test is a button
$("#test").on("click", function(){
$(".showhide").toggle();
});
you can find a fiddle HERE
As you can see, when some rows are hidde, the even/odd colouring is not respected. I tried this selector
table tr:nth-child(odd):not(.excludeme):visible{
....
}
but is not working.. Is it possible to accomplish this only using CSS?
Thank you
$(document).ready(function(){
$("#test").on("click", function(){
$(".showhide").toggle();
if($(element).is(":visible")){
// color odd rows
}
});
});
You have to verify the visibility of elements before coloring them. Only color the visible odd elements, not all elements in DOM (visible or not).
I hope that helps, have a good day :)
you can use following CSS(use of gradient CSS) without changing any other code:
* {
margin: 0;
padding: 0;
}
table {
padding: 0;
margin: 0;
border: none;
width: 100%;
background-image:
repeating-linear-gradient(white, white 1.2em, hotpink 1.2em, hotpink 2.4em);
border-collapse: collapse;
}
td,tr {
border: none;
padding: 0 5px;
line-height: 1.2em;
margin: 0;
border-collapse: collapse;
}
.showhide {
display: none;
}
.excludeme {
background: white;
}
I have a table which has a peculiar style issue when I insert an input element in the header. It does not center the input exactly; instead it is off by 2 pixels on the right side. I have some Twitter Bootstrap styles applied to the table, but I can't find one that is causing the issue so I don't think that has anything to do with it. Here is the markup:
<thead>
<tr>
<th scope="col" style="width: 5%;">
ID
<input type="text" value="" class="grid-filter" id="id-filter">
</th>
...
Here is a picture of the issue (zoomed in considerably):
Here are the styles applied:
th {
width: 15%;
a { display: block; }
input {
height: 15px;
line-height: 15px;
margin: 0;
padding: 5px 0;
width: 100%;
}
}
In the image above, I'm using Firebug and have focused on the "ID" anchor. As you can see, the anchor is correctly centered in the th, but the input box has an extra 2 pixels on the right for some reason. Why is this? The weird thing is that this does NOT affect select elements, only input elements.
Update: When I set the border and outline, Bootstrap's focus glow also has a border. Not sure which style to override...
edit: looks like the problem is your width attribute. Check this JSFiddle
HTML:
<table>
<thead>
<tr>
<th scope="col" style="width: 5%;">
ID
<input type="text" value="" class="grid-filter" id="id-filter"/>
</th>
</tr>
</thead>
</table>
CSS:
a, input {
padding: 0;
margin 0;
}
a {
display: block;
background: red;
}
input {
height: 15px;
line-height: 15px;
/* width: 100%; */
}
table { width: 3em }
The width attribute on the input defaults to auto, which does what you want in this case.
I have a table and I want each cell to have a red background if the cell is disabled, and blue if is enabled. So I have a inserted an invisible checkbox in each cell. When I have labels instead of a table, it works ok (see example here), but it´s not working with a table.
HTML:
<table id="hours">
<tbody>
<tr>
<td id="tdh00"><input type="checkbox" id="h00"></td>
<td id="tdh01"><input type="checkbox" id="h01"></td>
</tr>
</tbody>
</table>
CSS:
input[type=checkbox] { visibility: hidden; }
#hours input[type=checkbox]:checked + #tdh00 { background-color: #265BFA; }
#hours input[type=checkbox]:not(:checked) + #tdh00 { background-color: #FA2421; }
Try like below this is the solution with JQuery :
Fiddle : http://jsfiddle.net/RYh7U/138/
HTML :
<table id="hours" border="1">
<tbody>
<tr><td id="tdh00"><input type="checkbox" id="h00"></td><td id="tdh01"><input type="checkbox" id="h01"></td></tr>
</tbody>
</table>
</body>
CSS :
input[type=checkbox] { visibility: hidden; }
JQuery :
$("#hours td").each(function(e){
var ele = $(this).children('input[type=checkbox]');
var flag = ele.prop('checked');
if(flag)
{
ele.prop('checked', false);
$(this).css("background", "#265BFA");
}
else
{
ele.prop('checked', true);
$(this).css("background", "#FA2421");
}
});
$("#hours td").click(function(e){
var ele = $(this).children('input[type=checkbox]');
var flag = ele.prop('checked');
if(flag)
{
ele.prop('checked', false);
$(this).css("background", "#265BFA");
}
else
{
ele.prop('checked', true);
$(this).css("background", "#FA2421");
}
});
With your markup as it stands, this is not going to work. You are using the + (sibling) selector, but your table cells are not siblings of your checkboxes. In the example you gave, the markup is:
<div class="slideOne">
<input type="checkbox" value="None" id="slideOne" name="check" />
<label for="slideOne"></label>
</div>
Yours is:
<td id="tdh00"><input type="checkbox" id="h00"></td>
So, you are attempting to style the parent based on the state of one its child elements, which is not currently possible with CSS alone.
EDIT
Check out this working example. That fiddle adds the label back in (which will help with accessibility), and positions it in such a way that it visually does what you're after. The markup needs to be:
<table id="hours">
<tbody>
<tr>
<td id="tdh00">
<div>
<input type="checkbox" id="h00">
<label for="h00">Label</label>
</div>
</td>
<td id="tdh01">
<div>
<input type="checkbox" id="h01">
<label for="h01">Label</label>
</div>
</td>
</tr>
</tbody>
</table>
And the CSS:
table {
width: 450px;
margin: 0 auto;
}
td {
border: 1px solid #333;
padding: 0;
}
td > div { position: relative; }
input[type=checkbox] { visibility: hidden; }
label {
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: red;
text-indent: -999em;
}
input[type=checkbox]:checked + label { background-color: #265BFA; }
The extra div in each table cell is necessary, because Firefox can't handle positioning things relative to td elements.
Browser support is good, but only IE9+ is supported because we're using the :checked pseudo-class. You'll get better support with a JavaScript-based solution, but I'd argue that this is a great candidate for progressive enhancement.
EDIT 2
If support for old IE is a requirement, then you'll need to resort to JavaScript. Here's an example using jQuery.
The JavaScript just adds a class of active to the table cell: the bulk of the work is still done with CSS.
$("#hours input").on('change', function(){
var checkbox = $(this),
tableCell = checkbox.parents('td');
checkbox.is(':checked') ?
tableCell.removeClass('active') :
tableCell.addClass('active');
}).change();
The HTML remains the same, and the CSS differs only slightly with these lines replacing the :checked pseudo-class:
td { background-color: #265BFA; }
.active { background-color: red; }