The Quest for Scalable SVG Text

Written by Pete Corey on Oct 8, 2014.

In a previous post, I mentioned using SVG to create a scalable text logo. This got me thinking about using SVG text tags to create text blocks that would scale to fit in their parent container. I’ve seen lots of examples of this kind of thing in print media, but I haven’t seen it on the web. A great example of this style can be found on this seanwes blog post. I attempted to recreate the lettering piece from #3 in the code pens below.

ViewBox Magic

My first attempt was based around the idea of setting an SVG’s viewBox attribute equal to the bounding box of its child text element. This sets up the SVG’s coordinate system such that the text we want to render will perfectly fill 100% of the SVG’s canvas space. Because we’re not setting explicit widths and heights on the SVG element, it can be resized through our CSS. Setting its width to 100% causes it to grow to the width of its parent wrapper, and its height will scale in order to maintain the aspect ratio set up by the viewBox. In Chrome and Firefox this worked amazingly well! Check out the pen below:

See the Pen SVG Scalable Text - Chrome & Firefox by Pete Corey (@pcorey) on CodePen.

And Then There’s IE

Unfortunately, this approach had some issues in IE. While the SVG element correctly expanded to 400px, the height did not scale correctly. All of the SVG elements had a height of 150px. Strangely, the aspect ratios of the SVGs were maintained. The extra space above and below the SVGs seemed to be empty whitespace.

Thierry Koblentz’s intrinsic aspect ratio trick can be used to fix this IE problem, but the fix opens up another set of issues. This fix requires an extra wrapping div around each SVG element, and totally destroys the responsive aspect of using a bare SVG element. Any time the parent wrapper is resized, the top padding on the div wrapping the SVG must be recalculated **. Check out the pen below to see it in action:

See the Pen SVG Scalable Text - IE by Pete Corey (@pcorey) on CodePen.

Padding Problems

I’ve also been trying to figure out how to remove the padding above and below the text element returned by the bounding box. I tried to use getExtentOfChar to get a tighter height, but this seemed to return the same height as getBBox. Ideally, I would be able to have the SVG element tightly wrap the text and be able to specify my own padding/margin in the CSS.

If these issues can be solved (or even just the IE issue), I feel like this would be an awesome technique for creating some really amazing layouts and designs. If you’ve found solutions to either of these problems, please let me know!

Update - 10/9/2014

** For the IE intrinsic aspect ratio fix, I mentioned that I would need to recalculate the padding-top every time the outer wrapper was resized. That’s not true! In the code pen above, I was setting the padding-top to a pixel value, but I can just as easily set it to a percentage, which solves this problem. Check out the updated pen above!

Firebase! - T.U.S.T.A.C.R. Part 2

Written by Pete Corey on Oct 1, 2014.

After building out the frontend for thisurlshortenertotallyandcompletely.rocks, I was in need of a backend. I recently heard about Firebase, and figured it would be a perfect fit for this project. Check out a quick video overview and my rundown below:

Up And Running

I was blown away at how quickly I could get up and running with Firebase. With two lines of Javascript, I was persisting data to a server. I can’t find the words to describe how awesome this felt.

var ref = new Firebase("<endpoint>");
ref.set({hello: 'world'});

De-normalizing my Data

Most of my experience is with relational databases, not MongoDB style document stores or “NoSQL” databases. Because of that, my initial reaction is to see denormalized schemas as “wrong”. It took a good amount of time to convince myself that mirroring my data in two separate collections was the right way to go about things.

I played with the idea of somehow using Firebase priorities to get around this, but in the end I realized I couldn’t lookup data by URL and key without two separate collections. This is definitely just a mental shift that I need to get over when working with this style of database.

WebSockets!

One of the coolest things I found while playing with Firebase was the use of WebSockets to push events down to the client. I can see this being a huge deal when combined with something like AngularJS (AngularFire). Three way binding from the DOM all the way up to the database? Yes please!

I’ve been imagining something like a CQRS style system where commands are implemented as explicit calls (maybe even traditional REST PUT/POST/DELETE requests?) to the server, but all of the querying is done using Firebase style WebSocket endpoints that can automatically listen for data changes. I’m still fleshing these ideas out, but I’ll definitely be thinking more about this kind of thing in the future.

T.U.S.T.A.C.R

So that’s it! thisurlshortenertotallyandcompletely.rocks is finished and live. Watch out bitly, there’s a new sheriff in town!

Check out the project on github!

Frontend Workflow - T.U.S.T.A.C.R. Part 1

Written by Pete Corey on Sep 24, 2014.

I recently discovered Firebase, and I’m pumped about it. I wanted to make a small project to try it out, so I figured I’d make a URL shortener. Now, I’m pretty confident that this URL shortener is going to totally and completely rock, so I decided to name it thisurlshortenertotallyandcompletely.rocks. So, with a new small project in the works, I figured that this would be a great time to document my usual front-end workflow. You can see an overdubbed timelapse of the process and read through some of my thoughts about it below.

Sketch In the Browser

I’m a big fan of “sketching” in the browser. My usual workflow involves laying out my base DOM elements and applying some rough styles to get them behaving how I want. After that’s done, I like to open the page in Chrome and start playing with the styles using the Chrome Dev Tools. The immediate feedback is invaluable. Once I land on styles that I like, I’ll clean them up and organize them into my CSS/LESS/SASS files.

CSS Generators

When I’m in a hurry, or want to mock something up quickly, I tend to use online CSS generators (css3factory, css3gen). The visual feedback they give me is pretty useful when I’m designing-as-I-go. I used a few during the couple hours I spent on this project.

Responsiveness

On this project, I built the desktop version of the site first and added smaller viewport style changes at the end of the build. After the desktop layout was finished, I simply resized the browser until I found points where the content no longer worked. By “no longer worked”, I mean things like the header looked too large in proportion to the rest of the page, or where text was wrapping or overflowing, or where an element was pushed off of the screen, etc… When I found these places, I added media queries targeting that resolution to fix the issue.

Cross Browser Testing

I’m a huge fan of BrowserStack and I use it for all of my browser and device testing. Unless I am working on a potentially hairy feature, this is usually the last step in my process. I’ll run the site through each of the browsers I’m building for, look for issues, fix, rinse and repeat.

How to Improve

Looking back, there are lots of places where I can improve this workflow. First thing’s first, I should really ditch sketching in the browser in favor of some kind of LiveReload setup. This would eliminate the need to copy styles out of the browser and back into my codebase, and it would totally eliminate the mental context switching I have to do jumping from my browser to my editor.

I should also take more advantage of LESS mixin libraries. I tend to use online generators because of the visual interaction, but a LiveReload setup combined with a nice mixin library might make up for the lack of visual feedback. At the very least, I should transform the CSS I get from generators back into a LESS mixin for readability and maintainability.

Check out the final UI here. I’m planning on building out the Firebase/AngularJS/AngularFire “backend” next week. Stay tuned for another video and a blog post.