css to create zero-width non-space strings - css

Dear css experts: In my field, it is common to denote statistical significance with *'s on the numbers. I know I could put all stars in their own td field and then use css so that numbers are aligned, but I was wondering if this can be done in native css. the intent is to have an ability to realign numbers:
<html>
<head> <style type="text/css"> td { text-align:right; } </style> </head>
<body>
<table>
<tr> <th>c</th> </tr>
<tr> <td>1</td> </tr>
<tr> <td>11</td> </tr>
<tr> <td>111</td> </tr>
<tr> <td>1111</td> </tr>
<tr> <td>11<sup style="text-width:0pt">**</sup></td> </tr>
</table>
</body>
possible?

Yes, it’s possible, and it’s a novel idea (at least new to me). The idea is apparently to have a column with numbers, aligned to their last digit, but with one or more characters (here, asterisks) to the right of some numbers. Wrapping those characters to an element, setting the element’s width to zero, and letting the content overflow (overflow: visible, the default) does the job. However, the width needs to be set using the width property, which has no effect on inline (text-level) elements, and sup is inline by default, so this needs to be fixed by making it an inline block (which is affected by the width property):
<style>
td { text-align:right; }
.after { display: inline-block; width: 0; }
</style>
...
<tr> <td>11<sup class=after>**</sup></td> </tr>
I have used the same markup as in the question. However, the sup element has several technical problems (e.g., it may cause line misalignment), so I would use span instead. You can style it in superscript style if desired. But e.g. Chicago Manual of Style, clause 3.78, uses simple asterisk “*” characters in text in this context, with no attempt at raised position or reduced font size. The point is that in any many commonly used fonts, the asterisk itself is, by typographic design, superscript-like: above the baseline and relatively small.
Here’s a screenshot of a test that uses this technique, first with sup, then, on the last row, with span. The font is Cambria.

If I understand you correctly, you want to add '*' via css. You can do this:
td:after {
content: '*';
font-size: .8em;
vertical-align: top;
}
DEMO

Related

Possible CSS Specificity and Inheritance Bug with nested tables

Can anyone shed some light on this?
HTML:
<table>
<tr>
<td></td>
<td class="size20">
<div>Div 1 is font-size: 20px</div>
<table>
<tr>
<td>
<div>Div 2 should be font-size 20px because of inheritance and specificity</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
CSS:
.size20 {
font-size: 20px;
}
td {
font-size: 10px;
}
http://codepen.io/geoyws/pen/wGqqMB
The inherited value is only used when the cascade doesn't resolve a value for the given element. See "specified values" in the spec.
Your inner div has a font size of 10 pixels because it inherits from the inner td, which itself has a font-size: 10px declaration. The value that's inherited from all of the inner td's ancestors up to .size20 is ignored since the cascade has already determined a value for that td based on that declaration. Specificity is completely irrelevant because the .size20 selector doesn't even match the inner td in the first place. The fact that you're dealing with tables is also irrelevant.
Everything is working as designed. There is no flaw in either the specification or browsers as you suggest.
In css the last class effect will be overlaped by previous. It correctly inherits the size20 class but when it reaches td it overlaps the class size20 by td class.
If you again need size20 effect, then you need to add that class there. And that supress the effect of td, that's what happened in first div

Applying "page-break-before" to a table row (tr)

According to W3.org, the style page-break-after applies to block level elements (http://www.w3.org/TR/2004/CR-CSS21-20040225/page.html#page-break-props)
<tr> is a block level element (according to this: http://www.htmlhelp.com/reference/html40/block.html, it is)
I'm doing this, but the page break is not creating an actual page break when printing:
<table>
<tr><td>blah</td></tr>
<tr><td>blah</td></tr>
<tr style="page-break-after: always"><td>blah</td></tr>
<tr><td>blah</td></tr>
</table>
Am I doing this the correct way?
If <tr> wasn't a block level element: how am I suppose to achieve this page break?
Note: the before code is just an example, but what I'm trying to do is to put a page-break every 5 rows of the table, so if you know any tips for that case, will be appreciated
Inside <head>, set this style in your CSS stylesheet
<head>
<style>
#media print {
tr.page-break { display: block; page-break-before: always; }
}
</style>
</head>
That way, it will produce a page break during printing right before this table row.
<tr class="page-break">
</tr>
The site you referenced states that <tr> "may also be considered a block-level element since it may contain block-level elements." Neither the W3.org or Mozilla docs state that <tr> is a block-level element.
Some Possible Solutions
Based on the wording and your example, I would ensure that the cell contains a true block-level element. Here are two examples using <h1> and <p> which are block-level text elements.
<tr style="page-break-after: always"><td><h1>Next Section</h1></td></tr>
<tr style="page-break-after: always"><td><p>This will be a new page.</p></td></tr>
Others have reported similar problems and one of the solutions might work for you.
How to apply CSS page-break to print a table with lots of rows?
Google Chrome Printing Page Breaks
Printing a Gridview - how to print n rows on each page using page break
page-break-inside doesn't work in Chrome?
As mentioned by My Lister, you could attempt to catch the printing action or generate a print version of the page that would separate the table out so you can obtain the desired page break after every five rows.
Set all <tr> tags with display:block and define the page format and the size in mm for the table and cells.
Here <td> tag width is set to 23mm as there are 10 td tag with 2mm padding each side (23+2+2)*10=270 which is <table> width.
You can adjust word-break depending on how you want to break the words.
#media print {
#page {
size:A4 landscape;
margin: 5mm 5mm 5mm 5mm;
padding: 0mm 0mm 0mm 0mm;
}
.table{
width:270mm;
min-width:270mm;
}
td, th{
padding: 2mm 2mm 2mm 2mm !important;
display: table-cell;
word-break:break-all;
width:23mm;
min-width:23mm;
}
tr{
display:block;
}
tr.page-break {
page-break-before: always;
}
}

:before pseudo-element causes gap in border

I have this piece of HTML that I want to style.
The html is a table (and actual table), which I want to give a border.
The element also had a :before pseudo-element, which I use to put a small triangle in the top corner.
The JSFiddle is here.
I hope it makes sense. I stripped down the markup and the CSS as much as possible, because it's actually a small part of a big site.
http://jsfiddle.net/GolezTrol/28yDb/2/
Now the problem is that the combination of having 2 columns, having border-collapse: collapse; on the table and the :before pseudo element, cause the top border of the element to partially disappear. It's only there for the length of the first column.
You would assume that it is the pseudo element that is on top of the border, but this element is very small, and as far as I can tell, this could not be the problem. I added visibility: hidden; to the pseudo element to be sure, and I can tell that the triangle is gone, but the border is still incomplete.
Unfortunately I cannot change the markup, since this is outputted by MediaWiki, but I do have full control over the CSS.
The HTML:
<div id="globalWrapper">
<div id="column-content">
<div class="thumb tright">
<table class="infobox vcard" style="">
<tbody>
<tr>
<th colspan="2" class="fn org" style=""> Example text</th>
</tr>
<tr>
<th>Row head</th>
<td>Content</td>
</tr>
The CSS:
/* Generic table styling */
table {
border-collapse: collapse;
/*border-spacing: 0;*/ }
/* The box */
.thumb.tright table.infobox.vcard {
border: 3px solid #fae104;
position: relative;
}
/* Triangle */
.thumb.tright table.infobox.vcard:before {
content: "";
position: absolute;
width: 0;
height: 1px;
border-top: 5px solid transparent;
top: -7px;
border-left: 10px solid #555;
visibility: hidden;
right: -1px; }
I already found out that it works when I remove border-collapse: collapse;, but I'm not sure that is a proper solution, and even if it is, I would really like an explanation of what is going on.
Btw. I got this problem both in Chrome 29 and in Internet Explorer 10. Haven't tested other browsers.
Update
Instead of using -or not using- 'border-collapse' to fix the problem, I found out that this also works:
.thumb.tright table.infobox.vcard tbody {
display: block;
}
So the table itself is still a table, the pseudo element is still on the table, as is the border, positioning etc. The tbody, which was unstyled before, is now a block and the problem is solved in both browsers. I found this by trial and error, and still wouldn't know the reason behind it.
Updated fiddle: http://jsfiddle.net/GolezTrol/28yDb/9/
Being a newbie to StackOverflow and jsFiddle I updated the Fiddle with that I think is the solution. I didn't change the CSS except for moving the pseudo class from the table itself to the table header, and changing it into :after. Works for me in Firefox and Chrome!
/* Triangle */
.thumb.tright table.infobox.vcard th:after { }
Border-collapse: seperate is not supported in IE8 but I think this will be.
edit: nevermind ;)
It is a problem only occur on Webkit browsers I think. It can be considered a "browser bug" imo.
th should be inside thead, not tbody:
<thead>
<tr>
<th colspan="2" class="fn org" style=""> Example text</th>
</tr>
</thead>
<tbody>
<tr>
<th>Row head</th>
<td>Content</td>
</tr>
<tbody>
And I think this is the correct solution. You are putting an element where it is not advised to be, so it should be normal for a problem to occur.
Edit: as thirtydot pointed out, changing the th to td doesn't change the result. It only work when I moved the th to the thead section. At this point I am at a loss, I can't find a way to solve this.
But at least I think I can provide my speculation on the cause of this problem:
:before create a pseudo element inside the target element. What kind of element is unknown to me, but I suspect that the browser create a td. If that is true, then after rendering your html should look like this:
<table>
<td></td> /*the pseudo element*/
<tbody>
<tr>
<th colspan="2" class="fn org" style=""> Example text</th>
</tr>
<tr>
<th>Row head</th>
<td>Content</td>
</tr>
<tbody>
</table>
Needless to say this look weird. And if you try the above html out you can see the result is similar to your problem. border-collapse:collapse will merge 2 borders together where there are 2 cells next to each other, or a cell is next to the table's border. So I suspect in this case, the pseudo element - which doesn't have appropriate colspan - last only 1 column, the rest of that row is empty: nothing's there. This is where I think caused the bug: because there's no cells next to the table border there, no border is created at all.
The real reason may be a little bit more complicated ("why doesn't the bug occur when I put in a thead?"), but I think my answer is not too far off the mark. :)
The only reasonable explanation I can think of is pseudo-element :before not being compatible with the display: table of the table in collapsed mode. That is why border-collapse: separate; solves the problem. Suddenly, the browser can display the top border not caring about the pseudo element.
If you look closely, you can clearly see that the missing part of the border is the width of the second column. If you change it to after pseudo element, the border is missing in the bottom-right corner, again due to the fact that the borders of the table and the pseudo-element are collapsed.
If you change the border-bottom of th to be 3px solid red in collapsed mode, the th overpowers the table and the border is red. I presume, the power of after and before follow the same rule. It would be nice if someone who knows the specs better came to answer that.
Thinking this way, I do not believe there can be any other solution than:
using separate borders
putting the pseudo element on the parent div
What I inspected is that the pseudo element is actually rendered as block and can be change to table and list-item. However, none of these change the behaviour.
Very random stuff that is actually compliant with Av Avt's answer about where the pseudo element is rendered in regards of the DOM.
If I append the :beofre like this, the border stays:
.thumb.tright table.infobox.vcard tr:before
Obviously, it creates as many new pseudo element as there are rows.

Stop td making other tds above and below same width

How can I stop a td with lots of text making the td above it the same length?
In this example the outline for the cell containing '1' shows its as wide as the cell containing 'long text here'. What I want is for the cell containing '1' to only be as wide as it needs to be to fit the text it contains.
Can this be done with CSS?
http://jsfiddle.net/r7yXD/1/
<table>
<tr>
<td>1</tRund>
<td>2</td>
</tr>
<tr>
<td>long text here</td>
<td>.</td>
</tr>
</table>
td {
border: 1px solid red;
}​
So looking at the image below, the first example is what happens and I understand why, but can I make the 2nd option happen instead with CSS?
​
You can't. Its the nature of a table to make the td's the same width.
You could however add additional td's and use colspan="2", but to be honest, if you need to do such a thing, especially for texts, you probably shouln't be using tables.
Have you tried something like this
<style type="text/css">
td {
border: 1px solid red;
}​
</style>
<table>
<tr>
<td>1</td>
<td colspan="2">2</td>
</tr>
<tr>
<td colspan="2">long text here</td>
<td>.</td>
</tr>
</table>
As stated in the comments this is not possible using a <table>-element. You can read more about it here at w3.org: "17.5 Visual layout of table contents".
It says:
The visual layout of these boxes is governed by a rectangular, irregular grid of rows and columns. Each box occupies a whole number of grid cells, determined according to the following rules.
And interesting for your case is from rule number 5:
[…] Each cell is thus a rectangular box, one or more grid cells wide and high. […]

text-align on a table in a cell (<table> inside a <td>)

Here's something I never thought I'd say: I have a problem in Firefox and Chrome, but it's working fine in IE!
It's very simple, but I don't understand why it doesn't work:
I have a table inside a cell, and I have style="text-align:right" on the cell, but the table is staying left in Firefox and Chrome (in IE it's obediently going to the right...). If I put align=right in the cell tag then it works, but I don't want to do that.
Code is basically:
<table width="1000" border="1" cellpadding="0" cellspacing="0">
<tr>
<td style="text-align:right">
<table border="1">
<tr><td>Hello</td><td>Hello 2</td></tr>
</table>
</td>
<td>Hello 2</td>
</tr>
</table>
I don't want the nested table to be width=100% or anything like that...
Could anyone please explain to me why it doesn't work, and how to fix it, and maybe why it works in IE but not Firefox or Chrome?
My guess is that Chrome and FF are actually the ones rendering it correctly. text-align probably isn't supposed to affect table elements. However, applying float:right to the table will do what you want.
I would like to add that the CSS way to align tables relative to its container is with the margin property.
You must add margin: 0 auto; if you'd like to align it to the center, or margin-left: auto; if you'd like to align it to the right.
As #maxedison says, text-align will work only with inline and inline-block elements, so the other solution is change your inner table to take some of those display values.
You also need to remember that text-align works from 'container-to-content', this means it is normally applied to a container to affect its content (applied to a p to affect its inline content such as the text within), and margin: 0 auto works from 'content-to-container', meaning that it's normally applied to a block element and affects its position related to its container (applied to a div to center it to its parent).
If you want to fix it (not with full functionality), you can write this:
table {
display: inline-block;
}
This makes your table able to be centered with text-align: center;, if applied to the parent element(s).
when you don't want the div to be floating, you may try this :
http://jsfiddle.net/NvEZ8/
<div style="text-align:right;">
<table style="display:inline-block">
<tbody>
<tr>
<td></td>
<td>one</td>
<td>two</td>
</tr>
</tbody>
</table>
</div>
It looks like text-align (with a DOCTYPE html) only affects inline-block in Chrome and not inline only element. Replacing inline-block by inline here and it doesn't work anymore on my Chrome

Resources