The One with the Thoughts of Frans

Archive for CSS

Custom page number count in Prince

Prince makes it really easy to do all of the usual things with page numbers, like a different numbering scheme in the front matter and whatnot. Unfortunately you can’t counter-increment on @page, but thanks to Prince.addScriptFunc() you’ve got something better.

h2 {counter-reset: page 50}

@page {
	@bottom-left {
		content: prince-script(fixpagenum, counter(page));
		margin-left: 2cm;
	}
}

In this CSS, instead of passing regular generated content, we’re passing a prince-script. That script has to be defined somewhere, like this.

Prince.addScriptFunc("fixpagenum", function(pagenum) {
	pagenum = Number(pagenum);
	pagenum = pagenum + pagenum - 50;
	return pagenum;
});

The rationale in this case was to generate two separate documents, starting at page 50, one only left pages and the other only right pages. (Of course, the other one started at page 51.) I combined them with pdftk’s shuffle command.

pdftk left.pdf right.pdf shuffle output combined.pdf

I don’t think there’s a way to do something like this purely in Prince using CSS, but I’d love to be proved wrong.

Comments

Cutting Corners With Linear Gradients

Presumably unnoticed by all, back in December 2012 I replaced the image-based cut corners in post headings with pure CSS. Border-radius removed the need for images to round corners, but you don’t need images anymore to cut them either.

Edited down to only the cutting of corners, this is what it looks like now:

.posttitle a {background:#0b0; background:linear-gradient(225deg, transparent 8px, #0b0 8px)}
.posttitle a:hover, .posttitle a:active {background:#6c0; background:linear-gradient(225deg, transparent 8px, #6c0 8px)}

And this is how it used to be:

.posttitle a {background:#0b0 url(images/posttitle.gif) no-repeat top right;overflow:hidden;}/*overflow:hidden for Webkit which insists on adding some kind of margin*/
.posttitle a:hover, .posttitle a:active {background:#6c0 url(images/posttitle.gif) no-repeat 100% -91px;}

Size-wise the difference is small: the GIF was only 107 bytes. You’d pretty much make up the difference by adding prefixed versions of linear-gradient if desired, albeit you do still save an HTTP request and you avoid one of Webkit/Blink’s bugs.

For scaling it matters only very little. But not having to open up an image editor for simple things like this? Fantastic.

Comments

How To Fix SVG Height in Webkit/Blink

It’s pretty simple: also specify a height if you specify a width. To quote from the workaround in my stylesheet, which I added on account of my previous post:

figure svg {
	width:100%;
	/*what follows is because Webkit/Blink is broken https://bugs.webkit.org/show_bug.cgi?id=68995*/
	height:100%
}

I really shouldn’t have added that as I don’t cater to broken browsers anymore, but I have a bit of a soft spot for Opera—even if it’s never required any workarounds before. Presto is clearly superior, and so is Gecko. Chromium still doesn’t support SVG favicons. Gecko does. And just look at this table. Unfortunately Gecko doesn’t support SVG fonts, so it’s all looking pretty miserable without Presto.

Comments (1)Tags:

Taking Sidenotes to 2010

Five years ago there were lots of posts dealing with people’s visions of the least-bad method to include sidenotes — or footnotes — to HTML, and like any self-respecting HTML-geek I created my own take on the matter. As might be expected from five year old writings it is now outdated, and I’m glad it is. It means the cruft can be retired, and media queries can be used to their full glory — except in IE8, that is.

The script I wrote to supply non-Opera browsers with faux-media-query functionality assumes that any browser not Opera should have the script applied to it, because at the time Opera 7+ was the only browser that supported media queries. I knew this wasn’t exactly the proper way to write scripts, but it was meant to be updated to use some more intelligent detection at some point. As such things go, however, it never was. In my defense, the worst the script did was duplicate some functionality that was already provided by media queries, so I rather doubt anybody noticed any adverse effects. Heck, they might have noticed positive effects, since as I wrote at the time, “For now, it might even be the best solution to apply the Javascript to Opera as well, because Opera does not reapply media queries on resize yet (and it does fire the onresize event as every browser does).” For good measure I’m also including the script as I used it on my website since 2006. It has this nifty little added feature that it doesn’t actually do anything if there are no sidenotes present, which is something media queries cannot do. I think I considered writing a more intelligent check based on style features that would be set by the media query back in early ’06, but I can’t recall why I never did. For those interested in hacking the old script, the way I set it up it should be possible to determine whether media queries are supported very easily by combining a test for at least medium width with the marginRight style property on the sidenotes. If set, media queries are working; if not, go ahead and do some scripting magic.

Now, on to the updated sidenotes. I abandoned absolute positioning in favor of going completely for float. I believe I wanted to do this originally, but there were too many float bugs in all kinds of browsers to make it viable (that means everything not Presto or KHTML). Since these appear to be fixed, there is no reason not to take full advantage of floats, which most important means using clear so that sidenotes will not overlap.

I still think my original reasoning is quite valid, however, which means I don’t think sidenotes should be inserted lightly or contain overly long texts.

Let’s start out. How do we markup a sidenote? Well, as HTML contains no way whatsoever to markup a foot- or sidenote, the logical choice is small. Why small? Well, it means that the content of small is less important. A footnote should not be a footnote at all if it’s as important, or more important than the text itself, right? Thus, the markup of the sidenote is as follows:

<small class="sidenote">A sidenote</small>

This is still what I use, but ASIDE would be more appropriate in HTML 5.

The sidenote as I created it is meant to be put at the end of a sentence, inside a paragraph. Therefore it would be displayed at its original position in the text if author CSS was disabled, or read at its intended location on screenreaders. If it wouldn’t be put as a separate sentence, it would look strange if not displayed the intended way. The sidenote is placed inside the paragraph with the other text, for if it would require multiple paragraphs, should it be a sidenote?

There is one issue I didn’t take into account five years ago. For example, including two paragraphs or so of background information on a country or city in a sidenote would be an appropriate use of sidenotes since it’s not really a part of the text. My original stance (although not explicitly written) was that this should be solved with hyperlinks, but I have somewhat revised this stance. The markup would then become something like:

<div class="sidenote">
	<h3>Were Sidenotes Always Compatible With Any Element?</h3>
	<p>You could always apply the <code>sidenote</code> class to any element, such as <code>P</code> or <code>DIV</code>.</p>
</div>

Or in HTML 5:

<aside>
	<h3>Were Sidenotes Always Compatible With Any Element?</h3>
	<p>You could always apply the <code>sidenote</code> class to any element, such as <code>P</code> or <code>DIV</code>.</p>
</aside>

The main sidenote CSS is still very similar to what it was in 2005.

.sidenote {
	background: #efd;
	display: block;
	float: right;
	clear: right;
	width: 200px;
	border: 1px solid #eee;
	border-right: 0;
	margin: 2px;
	margin-right: -20px;
	padding: 3px;
	text-indent: 0;
	cursor: help;
}
.sidenote:before { content: '\2190' ' '; }
.sidenote:hover {
	background: #ff0;
}
/* enable usage of code in sidenotes without the layout breaking  */
.sidenote code {
	white-space: normal;
}

There are a few minor differences, but other than the addition of the .sidenote code line nothing worth mentioning. Only a few weeks ago I noticed that adding a line of code to a sidenote somewhat broke my layout because it stretched beyond the viewport. A few more global ways to accomplish normal white space in sidenotes come to mind (such as !important in the main class or .sidenote *), but from what I understand using such methods increases parsing time, if only ever so slightly.

The media queries performing the sidenote magic were significantly slimmed down, and a low-resolution in-line display was added:

@media all and (max-width: 350px) {
	.sidenote {
		display: inline;
		float: none;
		border: 0;
		margin: 0;
	}
	.sidenote:before {content:"";}
}
@media all and (min-width: 750px) {
	#wrapper{margin-right:207px}
	.sidenote {
		border-right:1px;
		margin: 0;
		margin-right:-228px;
	}
}
@media all and (min-width: 980px) {
	#wrapper{margin-right:auto}
}

Switching completely to float makes it possible to keep the overrides to a minimum, but that’s not the important change here. I switched to simple media queries for two reasons.

  1. It’s much easier to maintain and change. No more duplication.
  2. I don’t think most media types are as relevant anymore as I did back then. Specifically, in regard to such things as handheld devices what I want to do is offer different layouts based on screen size, not on whether they consider themselves to be handheld, screen, or some other fancy media type. Safari on the iPhone considers itself a big browser, for instance, but should it really get the “big” layout? None of this is especially relevant for my sidenotes, but it does reflect my opinion on it. Additionally, specifically overriding for certain media types rather than being specifically inclusive makes sure that no one is left out. In other words, this is future-safe. If the media type magazine ever emerges (they already did a magazine with an eInk cover, didn’t they?), my media query is ready for it now. And for those who care about such things, it also avoids an IE bug or two.

That’s it. My sidenotes are ready for the nearby future. They’re so 2010. Feel free to use or expand on my ideas, but please add a link back to me somewhere if you do.

Comments

IPA Fonts on the Web

Nowadays, the most obvious way to blend all kinds of UTF-8 characters in nicely with all the other text on your page might be Webfonts, but I think there are definitely valid reasons not to utilize those to achieve consistent display of IPA characters on a page. This post will focus on a very simple method which ensures that IPA will look decent across a variety of operating systems and browsers. The issue is nothing but aesthetics; however, the importance should not be underestimated as the following screenshot will demonstrate.

ipa-font-test
You can try the results of this yourself, but what it will look like depends on the fonts you have installed.

What I used to achieve the cohesive look of the IPA characters is this simple line of CSS.

.IPA{ font-family: "DejaVu Sans", "Lucida Grande", "Lucida Sans Unicode" }

It’s an easy concept. Slap class="IPA" on some element—I used SPAN—and it will automatically display in one of these fonts, ensuring that no characters look out of place. DejaVu Sans is a font I like a lot; It comes pre-installed on most Linux installations, and is freely available for everybody else. Lucida Grande is a font with the sufficient characters that comes with Mac OS X, and Lucida Sans Unicode is a font that, as the name implies, is very similar to Lucida Grande. It is available in Windows 98 and up.

References

“DejaVu Sans.” Wikipedia: The Free Encyclopedia. 12 Dec 2009 <http://en.wikipedia.org/w/index.php?title=DejaVu_fonts&oldid=329693253>.
“Lucida Grande.” Wikipedia: The Free Encyclopedia. 12 Dec 2009 <http://en.wikipedia.org/w/index.php?title=Lucida_Grande&oldid=314108882>.
“Lucida Sans Unicode.” Wikipedia: The Free Encyclopedia. 12 Dec 2009 <http://en.wikipedia.org/w/index.php?title=Lucida_Sans_Unicode&oldid=324714228>.

Comments