I'm using CSS counters to create a set of lists and subheadings. Here's the CSS
div.question {padding-left:2.5em; text-indent:-2.5em; counter-increment:item}
div.question:before {display:inline-block; width:2em; margin-right:0.5em; text- align:right; content:counter(item, decimal)}
div.subheading {counter-increment:none; counter-reset:item}
div.subheading:before {display:inline-block;content:none}
A Div with the class "question" should be numbered, whereas a div with the class "subheading" should have no numbering and should reset the numbering back to zero, so the next question will be 1.
This works fine in all the browsers I've tested it on as long as the content is static. However, if I use javascript to change the class from question to subheading Chrome won't reset the counters. This works fine in Firefox (v19) and Internet Explorer 8
There's a JSFiddle here
http://jsfiddle.net/NW43P/1/
As you can see the first subheading, which is loaded statically, correctly resets the counter. However, the second Heading, which is generated dynamically, fails to reset the counter.
I'm not sure if this is a bug in chrome or a problem with my code (I'm betting the latter), but does anyone know of a fix?
Thanks for any help
try reset the subsection counter in the section tag and increase the counter in the section:before. This works for me in the Chrome.
Example:
/* Header Numbering */
h1 {
counter-reset: h2ctr;
}
h1::before {
counter-increment: h1ctr;
content: counter(h1ctr) ". ";
}
h2 {
counter-reset: h3ctr;
}
h2::before {
counter-increment: h2ctr;
content: counter(h1ctr) "." counter(h2ctr) " ";
}
Maybe you can't edit the :before and :after pseudo elements? Or when you change the DOM after page is loaded.
For a fix, you could maybe consider using an ordered list? Instead of using the counter element? It would also be less code I guess?
Related
I've searched tirelessly and although I've found many people asking about this problem, there don't seem to be any consistent solutions.
We have a page on which a user can enter a date range, then press submit to return a table of data. A "print" button exists which obviously prints the generated data.
All browsers seem to be able to split the long table into several pages, as expected. We can also get some predefined footer text to show up on each page by using a footer div with some CSS like this:
.footer {
position: fixed;
bottom: 0;
}
The only problem is that the table rows have inconsistent heights, so on some pages there's plenty of room for the footer, but on other pages the table and the footer overlap.
Things I have tried:
#page {
margin-bottom: 10mm;
}
Adds a margin, but the bottom: 0; fixed position of the footer is now considered to be too high up, i.e. there's still an overlap but with a bunch of space at the bottom of the page. Setting the bottom property to a negative value just makes it appear at the top of the next page instead.
#page {
padding-bottom: 10mm;
}
No noticeable effect at all.
...And that's pretty much all I can think of. What can we do about this? Do we need some kind of custom JS solution to calculate the number of rows on each page and insert a footer manually? There must be somebody who has had success with printing footers; it doesn't seem like an uncommon requirement.
Please try to add this at the bottom of css file or after the last body affecting rule eventually adding also !important:
#media print {
body {
padding-bottom: 10mm;
}
}
There may be a more elegant solution, but you can do this in JS with an algorithm along the lines of:
while there is still vertical room left...
output a row to DOM
measure height of new row and recalc how much vertical room is left
For getting the height of an element, you could take a look at this other answer.
That may seem like a pain, but you'll have a lot of control over your rendering, and it should work fine.
i was having the same problem last day i search for hours to solve it. the solve was
adding these to css.
thead { display: table-header-group }
tfoot { display: table-row-group }
tr { page-break-inside: avoid }
ps: don't add relative position to the table never because it wouldn't work properly.
so I've been toying with this calendar-ish thingy for a bit:
Grid of divs (mimicking a table)
Hovering over a table cell displays a tooltip with 2 icons each consisting of a div with :before and :after elements
Icons change colour depending on colour of cell hovered and that of its previous sibling (cell's colour class is applied to the icon).
Stripped down fiddle: http://jsfiddle.net/e9PkA/1/
This works fine in every browser but IE8 and below (IE lte 7 and I will never friends, but IE8 would be nice to have).
IE8 notices the change of classNames and updates the divs' colour accordingly but completely ignores the colour changes implied by the :before and :after declarations, e.g.:
.wbscal_icon_arrival:before {
width: 12px;
height: 4px;
left: -8px;
top: 6px;
background-color: silver;
}
.wbscal_icon_arrival.wbscal_full:before {
background-color: #ff0000 !important;
}
In the fiddle above, the :before/:after elements are coloured exactly once: the first time the tooltip is shown.
In another version it would update everytime I'd move the mouse out of the "table" div, but not if the tooltip is hidden when hovering a "cell" div border.
I've tried force-triggering repaints by adding/removing other classes to/from the element/its parents/the body, editing/accessing style attributes and whatnot so I guess it's not your average repaint problem.
Is there a JS hack that fixes this and forces :before/:after to update?
Been trying to figure out the same thing. Basically IE8 doesn't redraw the pseudo elements unless you make a change to the content. So I've modified your example here (just CSS): http://jsfiddle.net/lnrb0b/VWhv9/. I've added width:0 and overflow:hidden to the pseudo elements and then added content:"x" to each colour option where x is an incrementing number of spaces.
It works for me; hope it helps you!
Adding content:"x" to each declaration of the psuedo-elements and incrementing the number of spaces for each different state of the element DEFINITELY FIX the issue.
Basically, the idea is to tell IE8 that the content is slightly different in each state, so redraw the content for each state. So, if the content is the same, we 'fake' it with empty spaces. BRILLIANT!!
#lnrbob really nice answer!!
i had the problem that i used the before and after pseudos of a checkbox input, which are using some parent attributes for displaying their content (due to being easily able to implement translation there).
so they look like:
input:before {
content: "" attr(data-on) "";
}
input:after {
content: "" attr(data-off) "";
}
and the markup looks like this:
<div class="switch off" data-on="It is ON" data-off="It is OFF">
<input id="switch" name="switch" type="checkbox" class="off">
</div>
and the modification i do in jquery looks like this:
var mSwitch = $('div.switch'),
on = $.trim(mSwitch.attr('data-on')),
off = $.trim(mSwitch.attr('data-off'));
// remove any spaces due to trim
mSwitch .attr('data-on', on);
// add a space
mSwitch .attr('data-on', on + ' ');
mSwitch .attr('data-off', off);
mSwitch .attr('data-off', off + ' ');
and i call this modification after setting/removing classes to change the style of the "checkbox" which is rather a switch button in this case :D
so this way you do not get a stackoverflow from too much space characters if some hardcore testers auto click the input for an infinite time ;)
like that:
<div class="switch on" data-on="ON" data-off="OFF ">
Basically IE8 doesn't redraw the pseudo elements unless you make a change to the content, so you can modify like below:
.wbscal_icon_arrival:before {
width: 12px;
height: 4px;
left: -8px;
top: 6px;
background-color: silver;
content: '';
}
.active .wbscal_icon_arrival:before {
background-color: gold;
content: ' ';
}
I am having a similar issue in IE11 and Edge right now.
on hover, I try to change Content from 'v' to 'V'.
=> Doesnt work on any microsoft browser.
However, if I change the letter to something else ('w'/'W') or two letters('vV'), the icon changes. Yay Microsoft.
I have p.first_p:first-letter in my stylesheet, as I checked, it works well when class first_p is set in HTML. Problems start when I use javascript to find elements and then set their class.
Under Chrome and Opera it works fine (I need to check IE 8 and 9, and FF3).
FF 5.01 changes the class, but still pseudo class setting doesn't affect the element.
It seems that FF needs to 'refresh' css settings of element before pseudo class starts working, so I made rather dirty workaround - script replaces affected node with its clone.
Is there a better way to solve that issue? Some way to make FF recalculate everything it knows about node? Also that workaround isn't enough for IE 7.
Edit: yeah, pseudo-element not pseudo-class, my bad
It is definitely a bug. A possible work-around would be changing the display style of the element. Unfortunately, this needs to be done delayed, after the previous style change applied:
element.className = 'first-class';
element.style.display = 'inline';
setTimeout(function(){
element.style.display = '';
}, 0);
Demo: http://jsfiddle.net/pvEDY/3/
You're running into https://bugzilla.mozilla.org/show_bug.cgi?id=8253
Is it possible to not use javascript?
I'm guessing that you're applying first_p to the first paragraph of particular elements.
It possible for you to use the :first-child selector instead?
I'm not sure if this will work, but you could try something like the following, assuming you want to apply this to children of divs with class "copy"
.copy p:first-child:first-letter{
color: #abcdef; /* or whatever */
}
this definitely works and you don't need javascript, except for crappy old IE.
Alternatively you could try this:
.element p:first-letter{
font-size: 20px;
}
.element p + p:first-letter{
font-size: inherit;
}
This css makes any paragraph that is not preceded by another paragraph have a styled first letter. Would that solve your problem?
Wait, you want it to work in Firefox. Try this:
.element p:first-of-type:first-letter{
font-size: 20px;
}
It selects the first matching element. The :first-of-type pesudo-element is supported by Firefox, Opera, Chrome and Safari according to SitePoint's page for :first-of-type
I have a table with some css to hide/show columns. Each td has the classes "column" and "columnX" where X is the column number. The css looks like:
.column { display: none; }
table.show1 .column1 { display: block; }
table.show2 .column2 { display: block; }
The table starts out all hidden and the user turns them on. When this happens, a class is added to table like "show1" or "show2" depending on the column being shown.
This works great in FF, chrome, and IE8. But IE6/7 have an issue where a "column" does not become "display: block". However, if I go in the developer toolbar and toggle the css rule
table.showX .columnX {display: block; }
it works fine. It is like these old browsers do not know to update the table when done via javascript. Also, if I add a class like "show0" to the table to begin with (not in javascript), it works fine in IE6/7.
Any known workarounds for this?
Well, first of all, the correct display value for a table cell is not "block"; it's "table-cell". Now, that's a moot point for old versions of IE anyway, since they don't really understand that sort of fancy stuff.
Now the next problem is the fact that old IE (6 and 7, not 8) have this entertaining feature when initially rendering table cells: if, when the table is first rendered, a column of <td> (and a <th> at the top, if you like) elements is not visible, then subsequent changes to the DOM will never make it show up. It's just stupid that way; in fact I've asked the same question here.
What I've done to work around the problem is drop some JavaScript onto the page so that after the HTML is first rendered, some code can come back and then make the appropriate columns invisible. So long as they start off visible, they can be turned off and back on without incident afterwards.
I'm having issues getting Firefox to update a webpage when its class is changed dynamically.
I'm using an HTML table element. When the user clicks a cell in the table header, my script toggles the class back and forth between sorted_asc and sorted_des. I have pseudo element which adds an arrow glyph (pointing up or down) depending on which class the cell currently is.
.thead .tr .sorted_asc .cell:after {
content: ' \25B2';
}
The problem is, that when you click the cell header a second time, the page doesn't update the arrow... until the user mouses away from the element. I think it's a bug as it works fine in Safari, and as I don't see any :hover tags in my CSS or other entries that might interfere.
Anyone seen this before, or know how to work around the issue?
It's kind of cheesy, but since you're using javascript anyway, try this after you changed the className:
document.body.style.display = 'none';
document.body.style.display = 'block';
This will re-render the layout and often solves these kind of bugs. Not always, though.
This is 2014 and none of the proposed solutions on this page seem to work. I found another way : detach the element from the DOM and append it back where it was.
Would you be able to use different CSS to accomplish the same thing without relying on the :after pseudo-selector? You might be able to simple define a background-image which you align as needed (I assume you would want the arrow on the right hand side).
For example:
.thead .tr .sorted_asc .sorted_asc {
background: url(images/down_arrow.png) no-repeat right;
}
.thead .tr .sorted_asc .sorted_des {
background: url(images/up_arrow.png) no-repeat right;
}
I only suggest this since I assume there isn't a specific reason why you need to use the :after pseudo-class. If you do need to use it, please update.
The bug can still be triggered in Firefox 58. Thankfully the opacity trick also still works. Just make sure to time it correctly. You might need to set a timeout between opacity changes.