GATHER. A Graphic Novel by Anton Peck — Kickstarter
Anton is a fantastic artist. Therefore, this graphic novel will be fantastic. Therefore, you should back the hell out of it.
Anton is a fantastic artist. Therefore, this graphic novel will be fantastic. Therefore, you should back the hell out of it.
I got some great comments on my post about conditionally loading content.
Just to recap, I was looking for a way of detecting from JavaScript whether media queries have been executed in CSS without duplicating my breakpoints. That bit is important: I’m not looking for MatchMedia, which involves making media queries in JavaScript. Instead I’m looking for some otherwise-useless CSS property that I can use to pass information to JavaScript.
Tantek initially suggested using good ol’ voice-family
, which he has used for hacks in the past. But, alas, that unsupported property isn’t readable from JavaScript.
Then Tantek suggested that, whatever property I end up using, I could apply it to an element that’s never rendered: meta
or perhaps head
. I like that idea.
A number of people suggested using font-family
, citing Foresight.js as prior art. I tried combining that idea with Tantek’s suggestion of using an invisible element:
@media screen and (min-width: 45em) {
head {
font-family: widescreen;
}
}
Then I can read that in JavaScript:
window.getComputedStyle(document.head,null).getPropertyValue('font-family')
It works! …except in Opera. Where every other browser returns whatever string has been provided in the font-family
declaration, Opera returns the font that ends up actually getting used (Times New Roman by default).
I guess I could just wait a little while for Opera to copy whatever Webkit browsers do. (Ooh! Controversial!)
Back to the drawing board.
Stephanie suggested using z-index
. I wouldn’t to do that in the body of my document for fear of screwing up any complex positioning I’ve got going on, but I could apply that idea to the head
or a meta
element:
@media screen and (min-width: 45em) {
head {
z-index: 2;
}
}
Alas, that doesn’t seem to work in Webkit; I just get back a value of auto
. Curses! It works fine if it’s applied to an element in the body
but like I said, I’d rather not screw around with the z-indexing of page elements. Ironically, it works fine in Opera
A number of people suggested using generated content! “But how’s that supposed to work?” I thought. “I won’t be able to reference the generated DOM node from my JavaScript, will I?”
It turns out that I’m an idiot. That second argument in the getComputedStyle
method, which I always just blindly set to null
, is there precisely so that you can access pseudo-elements like generated content.
Dave McDermid, Aaron T. Grogg, Colin Olan, Elwin Schmitz, Emil, and Andy Rossi arrived at the solution roundabout the same time.
Here’s Andy’s write-up and code. His version uses transition events to fire the getComputedStyle
check: probably overkill for what I want to do, but very smart thinking.
Here’s Emil’s code. I was initially worried about putting unnecessary generated content into the DOM but the display:none
he includes should make sure that it’s never seen (or read by screenreaders).
I could just generate the content on the body
element:
@media all and (min-width: 45em) {
body:after {
content: 'widescreen';
display: none;
}
}
It isn’t visible, but it is readable from JavaScript:
var size = window.getComputedStyle(document.body,':after').getPropertyValue('content');
And with that, I can choose whether or not to load some secondary content into the page depending on the value returned:
if (size == 'widescreen') {
// Load some more content.
}
Nice!
As to whether it’s an improvement over what I’m currently doing (testing for whether columns are floated or not) …probably. It certainly seems to maintain a nice separation between style and behaviour while at the same time allowing a variable in CSS to be read in JavaScript.
Thanks to everyone who responded. Much appreciated.
Update: If you’re finding that some browsers are including the quotes in the returned :after
value, try changing
if (size == 'widescreen')
to if (size.indexOf("widescreen") !=-1)
. Thanks to multiple people who pointed this out.