Blog posts about Web development
-
CSS Specificity as semantic versioning
When thinking about CSS specificity, it can be tricky at first to understand how one selector beats another. It just occurred to me that semantic versioning could be a good way to explain it – provided you already know how the versioning scheme works.
Read the whole post "CSS Specificity as semantic versioning"
-
Custom properties for breakpoint debugging
Yesterday, I stumbled across Eric Meyer’s post on displaying CSS breakpoint information with generated content. It reminded me of a solution to a related problem that Jeremy Keith blogged about way back in 2012 – how to conditionally load content (via JavaScript) when a certain breakpoint is active. I realized that the technique could be improved using custom properties.
Read the whole post "Custom properties for breakpoint debugging"
-
Progressive Web Apps behind Basic Auth
When adding a service worker and Web App Manifest to a staging site recently, I ran into some small issues with HTTP Basic Auth. Here's how I solved them.
Read the whole post "Progressive Web Apps behind Basic Auth"
-
Smart borders between flex items – the dumb way
How to emulate a direction-independent border inbetween two flex-items, regardless of whether they wrap or not. Caution: it's the dumb.
Read the whole post "Smart borders between flex items – the dumb way"
-
Fixing fieldsets
The fieldset element is a really useful one. It creates a grouping of related form fields, giving them a label in the shape of a legend element. Sadly, it's a pain to style, but I think browser makers and spec writers have a unique opportunity to fix it.
-
Enquire Within Upon @media
When dealing with advanced layout features, it makes sense to place all of your CSS inside of a feature query, including media queries for the advanced layout. However, Chrome (currently) drops the ball on that last part.
TL;DR: You currently can’t quite nest media queries inside feature queries in Chrome, but the other way around is fine. This bug has since been fixed, and should go away in upcoming versions of Chrome.
-
Revisiting the Float Label pattern with CSS
The float label pattern is a slick pattern that designers seem to love. I’m not sure that I’m 100% in love with it, but I couldn't resist cooking up a quick demo implementation. This version uses a few nice form-styling tricks using modern CSS that I've seen recently, particularly the
::placeholder-shown
selector.Read the whole post "Revisiting the Float Label pattern with CSS"
-
Grid Tidbits part 3: grid track sizing
In this Grid Tidbit, we’re going to get into sizing the grid tracks – which means the rows and columns of a grid container. There’s all sorts of special functions and tricks that help us do so in a flexible way.
Read the whole post "Grid Tidbits part 3: grid track sizing"
-
Grid Tidbits part 2: terminology and basics
A walk-through of the basics of defining grid containers, what they're made of and how to place items inside them. This is the second part of my series on the CSS Grid Layout specification, "Grid Tidbits".
Read the whole post "Grid Tidbits part 2: terminology and basics"
-
Grid tidbits, part 1: the Why and Where
What is Grid Layout, and where can I use it? This is the first post in a series of reasonably short pieces on Grid Layout. Rather than give you the ”everything you need to know about Grid Layout” post, I thought I'd try to break it down into easy-to-digest pieces.
Read the whole post "Grid tidbits, part 1: the Why and Where"
-
Switching the blog to Django
I just switched the blog over to being based on a custom Django app.
-
IE, blurry SVG backgrounds and size rounding
Another small find for SVG background images in IE. Basically, IE is not great at rounding numbers.
Read the whole post "IE, blurry SVG backgrounds and size rounding"
-
Sizing SVG background images in Internet Explorer
SVG used for background images in CSS generally works pretty well. IE however has some weird sizing behavior of the rendered size of the SVG graphic that can bite you if you’re not careful.
Read the whole post "Sizing SVG background images in Internet Explorer"
-
Reset your fieldset
Starting off the new year with a blast from the past – wrestling with the very stubborn
<fieldset>
is sure to get your juices flowing! There's a million and one things wrong with styling this element, but fear not! There are solutions to be found. -
On class names, semantics and accessibility
In the debate about ”unsemantic” class names, accessibility is often brought up. I would argue that class names have nothing to do with accessibility, and that naming things is hard. In reply to an article by Heydon Pickering in A List Apart.
Read the whole post "On class names, semantics and accessibility"
-
Prepping the right thing
Brad Frost wrote a very good post called ”Primed and ready to go” on how developers can get working early on in a project, even if the design is not finished. I was nodding along, going ”yes, yes, yes”, but there were things about it that didn't sit quite right with me.
-
My setup and tips for cross-browser testing
A post with a long list of stuff I use to test on different browser versions, and how to set some of them up.
Read the whole post "My setup and tips for cross-browser testing"
-
Using JS Bin as an SVG playground
Some days I love the web more than other days. The other day, I had an idea for a feature request for JS Bin. A quick Twitter exchange with Remy and a filed issue on Github, and boom; the feature exists a day later. Now you can use the HTML panel on JS Bin to act as a source for SVG files! I'll explain how in this post.
-
Intrinsic sizing of SVG in responsive web design
A long and rambly exploration of how sizing of SVG content works (or doesn't work) in web pages. There's cake at the end.
Read the whole post "Intrinsic sizing of SVG in responsive web design"
-
Scoping margins
The one where I ask Twitter a question on setting margins in CSS, get some good replies and decide to get the blog rolling again by elaborating on my own answer.
-
Playing around with CSS variables - "custom properties"
Edit 2015-03-29: I've updated this post to reflect the new syntax from the spec.
To begin with, the name CSS variables is only partly correct. They are variables of a sort, but the correct name, and way of looking at it, is custom properties. The full name of the specification is "CSS Custom Properties for Cascading Variables". I have a hunch that the "Cascading Variables" part of the name is what makes it really interesting.
The basics
Let’s jump into some introductory examples. To create a custom property, you simply declare it, and make sure it begins with
--
, think of it as being likedata-
attributes on HTML elements – as long as it starts with a double dash (and is syntactically valid as a name), it's valid. The value can be any valid value for CSS. So to create a custom property (or variable, if you wish) that we can use anywhere in our document, we declare it using the:root
selector::root { --primary-color: firebrick; /* yes, that is a valid color keyword. pret-ty cool. */ }
To use this variable somewhere else, you can reference it with the
var()
function notation, passing in the property name. The second argument to the function is the fallback value, in case the custom property is not declared on an ancestor (and thus inherited) or invalid:.myComponent { color: var(--primary-color, #000); }
Using the cascade as variable scope
Declaring a custom property only on a specific selector means that it’s only reachable within the context of that selector, since it’s automatically inherited. Combining this with the fact that using custom properties can have fallback values, we can decouple specific styling from selectors, and couple them to the context of the variable instead.
One example that pops up in my head is when we have a part of a page that comes from a CMS, like a blog post: in that case, we might want to apply some sort of base styling that we don’t really use outside heavily of this context. The goal is to make the HTML inside of this block behave consistently, and not let that affect the rest of the page (which might be more "UI" than "content", if you get what I mean). I usually have some sort of classname, like
.flow
, that I use in these cases, and then style descendant selectors..flow p, .flow h2, .flow h3, .flow h4, .flow ul { /* Properties for nice consistent flow here */ }
Now, say that this styling relies on some sort of vertical rythm, sort of like Harry Roberts’ idea of single-direction margin directions. We can create a context where this is applied to descendants of the
.flow
class without really tying it to the selector itself, but instead tying it to the base styling of the elements themselves. An example to explain:.flow { /* set the var-flow-space custom property on elements inside .flow */ --flow-space: 1.375rem; } h2, h3, h4, h5, ul, p { /* If the var-flow-space is defined, apply that for margin bottom, otherwise 0 */ margin: 0 0 var(--flow-space, 0) 0 ; } }
This means that outside of the “flow” context, elements are normalized to have no margin, except
margin-bottom
if the--flow-space
property is inherited. We could, if we wish, define other contexts where we want to use a consistent margin-value for these elements, e.g. small-print: we just make sure to redefine the variable inside a selector that we use for that context.Going further: goodies from the spec
One of the first things that I tried (without reading up on wether it was possible or not) was to concatenate/interpolate other property values with the
var()
notation, likevar(--my-val)px
. This does not work. However, the spec mentions this case explicitly, and gives us a brilliant use of thecalc()
function to make this happen. We can simply create the units we want by operating on them::root { /* unitless number */ --vertical-base: 1.375; } .flow { /* use the number to set context-specific base number */ --flow-space: var(--vertical-base); } h2, h3, h4, h5, ul, ol, p, blockquote { /* Normalize, use calc to give the flow-space (if set) variable a unit */ margin: 0 0 calc(var(--flow-space, 0) * 1rem) 0; } blockquote { /* give blockquotes inside contexts where flow-space is set a consistent side padding */ padding: 0 calc(var(--flow-space, 0) * .5rem); }
Setting custom properties to read from scripts
Another thing that the spec mentions explicitly is setting custom properties to be read by JavaScript. This ties in nicely with the idea of not having breakpoints duplicated in both CSS and JavaScript, like what Jeremy outlined in “Conditional CSS” and that I (and others) proposed a solution to via using the <code>content</code> property alongside <code>getComputedStyle</code>.
Sadly, it does not seem possible to use custom property values inside media queries, like
screen and (min-width: var(--lapsize))
, which would possibly make authoring of media queries a bit more DRY. It is, however, fully valid to set variable values inside media queries, so we could do something like this:/* Yes, I know the category names are convoluted, but man, these things are hard. */ @media screen and (min-width: 25em) { :root { --screen-category: small-lap; } } @media screen and (min-width: 48em) { :root { --screen-category: lap; } } @media screen and (min-width: 80em) { :root { --screen-category: desk; } }
Then we can read these values by using the new JS API to get the value of custom properties, using something like this on resize etc:
var screenCategory = el.style.var.get(‘screen-category’);
This is not implemented in the Firefox Nightly, so I haven’t been able to play around with it yet. Edit: It seems this interface has been postponed in general, so it's not available yet.
I’ve put up the very quick-n-dirty source code for my experiments on JSBin. Download the nightly, play away!
Like I said in the beginning of the article, it’ll probably be a while before this is in all major browsers, and using it properly without massive fallbacks (thus negating the need for it) would be hard. I’m not sure how hard or easy it would be to polyfill in some way (probably hard), but for now it’s just massively fun to play with and try to figure out how to use once it’s there.
Read the whole post "Playing around with CSS variables - "custom properties""
-
Sticky footers, flexbox and IE10
I recently came across Philip Walton's excellent ”Solved by Flexbox” site, where he shows some good examples of using flexbox to create common layout patterns, some of which have been really tricky to solve with CSS until now. Since there's multiple versions of the flexbox syntax, the examples on Philip's site are (quite sensibly) only focusing on the latest, more stable version. When I tried out the example for ”sticky footer” with all of the different versions of the flexbox syntax, I found that it didn't work in IE10. This post explores how to fix that, as well as make it work in all other browsers that support old and new flexbox syntax.
-
Webmentioning Adactio
Jeremy has recently implemented Webmention on adactio.com, and posted an explanation of the small piece of code involved. I I love the simplicity of Webmention, and I love the Indieweb idea of connecting our conversations in the simplest possible way whilst still publishing to our own sites, owning our data. I intend to implement it on this site as soon as I can: both to test it out, and to offer a way of commenting without all the hassle of actually managing comments (sort of).\r\n\r\nI do have one teensy tiny criticism though: what's that little bit of tech-specific junk doing in the Webmention URL, Jeremy? ”Dot PHP”? Cool URI:s don't change, but publishing platforms and script languages do, right? Excuse me sir, your CMS is showing! :-)
-
My Metaphorical Job Title
I'm a web developer. At least that's what it says on my business card. If I have to be specific, I'm a front-end web developer. In practice, I do a lot of things that are not developer-y, and sometimes drift more towards a role that's probably normally labelled ”designer” of some sort. When people ask, I mostly try to say ”I build websites”. But behind that, what kind of developer am I really?
-
Progressive Enhancement: Still Not Dead.
There's been a lot of focus on Javascript the last couple of years. Sometimes, the best way of building a web property is described as just slapping a JS-driven app on top of a REST-API, and I have some issues with that. More specifically, I think the benefits of progressive enhancement are still misunderstood, and progressive enhancement is Still Not Dead. Layering support for user-agents, performance and being robust against broken or blocked JS code are very good reasons.
Read the whole post "Progressive Enhancement: Still Not Dead."
-
Viewport relative unit strangeness in iOS 6.
Using the new viewport-relative units in CSS3 is compelling when creating flexible layouts across different screensizes. It is early days though, and it turns out there are some issues in browser implementations that are worse than others–and iOS 6 is a doozy in this regard. This post explores what I think is the cause of its weirdness.
Read the whole post "Viewport relative unit strangeness in iOS 6."
-
Drowning
In which I have a bit of a Billy Joel moment. Tools, technologies, frameworks, methodologies, buzzwords, services... Sometimes I just get very, very tired.
-
On the value of testing on real devices
There's sort of this saying in the UX disciplines, that you never really know what you will learn when you do usability testing with real humans, but you will always learn something new every time you actually put the thing you're working on in someone else's hands. I can attest that yes, you do learn something every time, and you should try it. What I've found is that pretty much the same thing is true for doing varied device testing.
Read the whole post "On the value of testing on real devices"
-
Wrangling white-space
Some quick notes on problems with white-space and line-breaks in source-code not cooperating with the intended output, and how to deal with it, now and in the future.
-
About donating blood
Today I donated blood for the first time. I’ve been meaning to do that for a long time, but following the normal course of yak-shaving/bikeshedding etc, there was always some excuse for not doing it "now"—needing more info, not wanting to be tired ahead of some important activity, not knowing when the donation bus was going to be around etc etc. For some people, the idea of getting stung by a rather large needle might also be an issue.
I have a very rare bloodtype, where the plasma in my blood can be used for receivers with any blood type, so I’ve understood that my blood is really, really valuable for the people working every day to save lives. And from what I gather, they normally don’t have enough of any blood type. So the stuff spinning around in your head before making a decision to donate blood is keeping you from doing a very simple thing that is hugely important and helpful.
Here’s a list of stuff you should check right now, to go from maybe thinking about it but not doing it:
- There’s probably a site with most of the info you need about how it works in your country and/or city. Here in Sweden it’s geblod.nu. Go there, read up.
- There are very strict regulations about who can give blood: diseases, medication, medical history, travel habits, tattoos etc—all these things can be possible reasons why you cant give blood. Read up on them now: maybe you’re not even eligible to donate, and you can put this out of your mind for a while.
- Here, there are blood buses that go around various parts of town, and you can sign up for notifications when they’re in your area. If you think you are eligible to donate, do that, and at the nearest possible occasion, go and do the initial testing, it takes half an hour or so.
- It doesn’t hurt. Seriously, it’s a tiny needle sting. It’s not even close to like stepping on a lego piece. It’s a pretty big needle, but if that bums you out, just don’t look at it.
- You’ll be fine after donating, just maybe a little bit tired for a while. I can’t really tell the difference. I expected to be really tired and weak—not so. The advice is to not do physical excercise the same day, but you will not be completely out for the day, far from it. Of course, I’m not a doctor and your mileage may vary, etc.
So there. It’s not a big thing, it’s simple. Read up on if you can donate, get yourself tested, donate.
-
Hello
There's a lot of things that can stop you from getting your own site or blog off the ground, mainly fear of failure and too much tinkering.\r\n\r\nThis is the inaugural post, about how a tweet over a year ago got me agonizing over finally getting this thing out the door.