Happy Thanksgiving to everyone in the U.S. and a very belated Happy Thanksgiving to everyone in Canada. Happy Thursday to the rest of the world.
As has become tradition for me, I'm in New York visiting family and as usual I've been taking pictures of my trip, including our long walk yesterday in Manhattan.
For the last few months I've been reading and learning how to take better pictures with my iPhone, hoping to put what I've learned into practice. Then we walk through the city and I realize I barely have time to snap shots and so most of my learning went out the window. Still I thought I'd share some of the 300+ images I captured yesterday to give you a feel for what's going on.
Window Displays
One of the things we like to take in during our walk are the window displays in some of the department stores. It's hard to take pictures of them as there's little time where someone isn't blocking the view and the camera captures an equal amount of display and reflection of the city across the street.
Macy's went with a Peanuts theme this year. Perhaps not the most original theme, but who doesn't like Charlie Brown and the gang.
Lord & Taylor's had a candy and confection theme.
I was able to press my camera up against the glass of one of the smaller windows at Lord & Taylor’s that wasn't part of the theme and was able to get rid of the reflection on this shot.
For a change Saks had their display ready. It usually goes up after our visit. They had a wedding theme going and I like how the refection mixed with the display in this image.
St. Peter's Cathedral
Just past Sak's is St. Patrick's Cathedral. I find it hard to capture what you see in photographs, but hopefully these images give you a feel for what it's like to be inside such a beautiful building.
Egypt at the Met
Before going inside my brother and I were sitting next to the fountain in front of the Met. I tried putting some of my learning into practice by taking a picture in a puddle just outside the fountain and I captured this reflection of the museum and water from the fountain.
We only took in one exhibit this year. Egypt is part of the permanent collection at the Metropolitan Museum, but I don't think I've ever walked through the entire exhibit before.
Central Park
No walk trip through Manhattan would be complete without some time in Central Park. I love the colors of the park in the fall.
Parade Floats
15 years ago when we first stumbled on the parade floats being inflated, seeing them was a casual experience. Over the years more and more security has arrived and this year it was tighter than usual. We spent as much time trying to get out as we did checking out the floats.
I also realized that the older I get, the less I recognize most of the floats. I know the Kool-Aide guy, but I'm clueless who the other two are.
Happy Thanksgiving
I'll leave you with a couple of pictures of Christmas trees to get you ready for the coming holiday season. The first is the tree inside the New York Public Library The second is an origami Christmas tree from inside the Museum of Natural History.
Once again, have a Happy Thanksgiving, a belated Happy Thanksgiving, or the best Thursday you can have.
When you set coordinates to position SVG text, you're setting the location of the left edge of the text and you're setting the location of the baseline of the font. Last week I showed how you could adjust the former through the text-anchor attribute and today I want to show you how you can adjust the latter.
If you haven't been following along with this series about SVG text you may want to read the first post where I talk about things like font tables and EM boxes. I'll do my best to to keep things clear in this post, but an understanding of what's in the earlier post will probably be helpful.
Baseline Alignment
In the first post in this series I talked a little about font tables and how they include information such as the position to display the font's glyphs. Information about the location of the baseline of the glyph in relation to the EM box is part of the information in the tables.
Different fonts can have different baselines and so different points where they're located within the EM box. For example:
horizontal writing, ideographic scripts (Han Ideographs, Katakana, Hiragana, and Hangul) are aligned to a baseline near the bottom of the glyph.
alphabetic based scripts (Latin, Cyrillic, Hebrew, Arabic) are aligned to a baseline at the bottom of most glyphs, but some glyphs descend below the baseline.
Indic based scripts on the other hand are aligned at a point that is near the top of the glyphs.
If you stick with a single font there's no issue, but if you change fonts along the line it is. Changing fonts is possibly more realistic than you realize too.
For example it's not uncommon for two words in a logo to use different fonts or you might switch to a monospaced font to show code in the middle of a sentence. Depending on the fonts in question they might not align along the same baseline.
SVG uses a model that assumes a single font at a single size is the "dominant run" and all other baselines are defined in relation to it. Each font should provide information about offsets for the alternate baselines as well as an offset for math baselines in some math fonts.
The model further assumes each glyph has an alignment-baseline value to align the baseline of that glyph with the dominant baseline.
It's possible your head might be spinning after reading everything to this point. I know mine was when I first looked at baseline alignment and it's still spinning just a little so I'll skip further details.
The gist is the font tables associated with each font contain information about different baselines the glyphs might be aligned to and SVG uses the information to align the glyphs in different fonts relative to each other.
Baseline Alignment Properties
SVG provides three properties to allow you adjust these different baselines.
dominant-baseline – used to determine or re-determine a scaled-baseline-table
alignment-baseline – specifies which baseline is to be aligned with the corresponding baseline of the parent
baseline-shift – allows repositioning of the dominant-baseline relative to the dominant-baseline of the parent
My guess is, the last baseline-shift is the one you'll be tempted to use the most, but let me offer an example of each to try to illustrate how each can be used to refine the location of the baseline of the font you're using.
dominant-baseline
The dominant-baseline property can take any of the following values auto, use-script, no-change, reset-size, ideographic, alphabetic, hanging, mathematical, central, middle, text-after-edge, text-before-edge, inherit.
Instead of copying and pasting the definition of each I'll point you to the definitions in the spec. I'll present an example showing some of the values. I should mention the examples in this post won't work in Firefox, but they do work in Safari and Chrome. I haven't tested in other browsers.
In this example I created what should be a familiar <svg> element with viewport dimensions set along with some styles I hope are self-explanatory.
Inside the SVG I created six <text> elements. The first three are positioned so their default baseline sits on the top edge of the viewport and the last three on top of the bottom edge of the viewport.
The dominant-baseline of the first <text> element hasn't been adjusted. The other five have and I placed the value in parenthesis so you can see the value used.
If you'd like to see examples of the other values you can play around with the code or check here. If you do the latter the same browser warning from above applies.
alignment-baseline
The alignment-baseline property takes a similar set of values. They are auto, baseline, before-edge, text-before-edge, middle, central, after-edge, text-after-edge, ideographic, alphabetic, hanging, mathematical, and inherit.
Again I'll refrain from copying and pasting definitions of the values and point you one more time to the spec. I will present another example similar to the previous one, but using alignment-baseline instead of dominant-baseline.
The SVG element is the same as before. Because alignment-baseline is an adjustment relative to the parent element, I created two text elements, one at the top and one at the bottom and inside each I placed several tspan elements with different alignment-baseline values.
Again the value I used is in parenthesis to help you see the value as you're looking at the result.
I'll leave it to you to try the values I didn't use in these examples if you want to see what each does or you can check here with the same browser warning.
baseline-shift
Of the three baseline alignment properties, baseline-shift is probably the one you'll use most often and it has the fewest possible values.
The baseline-shift property "allows repositioning of the dominant-baseline relative to the dominant-baseline of the parent text content element." In other words it lets you shift text up or down or rather perpendicular to the direction the text flows when displayed.
The baseline-shift property takes four values (sub, super, <percent>, <length>) and the first two will give you an idea when and why you'd want to use the property. With the latter two values, a positive value moves the text up (super) and negative value moves down (sub).
In this next example I created four text elements, each with a <tspan> inside containing the number 2. I added the following baseline-shifts to the tspans from top to bottom in the code, sub, super, –60%, and 20px. The last two values I adjusted by eye to hopefully match the sub and super values.
My apologies for what might be another information dense and mostly dry post. My eyes glazed over a bit when I first took a look at the spec, but it's ultimately not all that complicated.
Fonts deliver information through font tables about where their glyphs should be positioned, including where the baseline of the glyph should be positioned.
Because different fonts will have different baseline information it's possible when using multiple fonts that they won't line up the way you want. When that happens you can adjust the three baseline properties so the glyphs are better aligned.
Next week I'll take a look at some properties you likely use all the time in CSS and show you how to apply them to SVG. We'll talk about font properties you know like font-family and font-size and some you might not know like font-stretch.
At the start of this series on SVG text I mentioned font tables. I said that certain alignment details for rendering a font's glyphs were contained inside those tables. I also mentioned at some point in the series we'd see how we could alter some of this information
When you position SVG text, the default is to display the left edge of the EM box and the baseline of the character at the position you specify. Both can be adjusted.
However, before we get to those adjustments let's talk about how we might display SVG text for international fonts. SVG includes support for international writing directions and we can change the default direction.
Writing Modes in SVG
You can use the writing-mode property to change the inline direction from the default, which is left-to-right. You can set the text to display either right-to-left or top-to-bottom instead.
It works like the css writing-mode property which does the same thing. In SVG, writing-mode is an attribute with the following values.
lr-tb | lr — either sets direction as left to right (default)
rl-tb | rl — either sets direction as right to left
tb-rl | tb — either sets direction as top to bottom
The values above show there are two ways to set the specific value you want depending on which direction you want the text to flow. I'll stick to the two character values and save the extra bit of typing.
As always let's start with an example and build on it. I created an SVG element, set the viewport size, gave it an outline, bumped up the font-size, and set the overflow to visible in case any text renders outside of the viewport.
I set the writing-mode as tb or top to bottom and you can see the text flows vertically, though the characters are now rendered on their sides.
Unfortunately I haven't been able to get a left-to-right writing-mode working at all. The values I showed for writing-mode have been deprecated for everything other than SVG, though they should still work with SVG.
There's a different set of values if you want to use the CSS writing-mode property, though the values don't include a right-to-left direction.
Regardless of my issues you should be able to set the writing-mode so it renders right-to-left using either rl or rl-tb as the writing-mode value.
Let's get back to the example again and note that while the text was rendered from top to bottom, the characters are also rotated 90 degrees. You might think the solution is to use the SVG rotate attribute and set them back.
Note that 0 is the value to get the characters to sit upright, which may or may not be what you expect.
I'll let you experiment with the other values. This probably isn't something you'll use in practice a lot unless you often use a writing-direction of top-to-bottom as some Eastern Asian languages do.
Then again, it's possible you just want to get creative and play with different writing-modes and glyph orientations.
The text-anchor Property
By default when you position SVG text the position you specify is aligned with the left edge and the baseline of the text.
One property you may find useful is the text-anchor property, which lets you align text horizontally at the start, middle, or end of the EM box.
Here's an example comparing all three values. I set three lines of the same text at different y-coordinates. All three lines have an x-coordinate of 0 so we can see how they render against the left edge of the viewport.
I set the text-anchor of each to the three different values. You can probably tell by looking which line of text has which value set, but the order from top to bottom is start, middle, end.
There are also some properties for adjusting SVG text along the baseline, but let's save those for next week.
Closing Thoughts
The writing mode of SVG text can be changed from its default left-to-right orientation to display either right-to-left or top-to-bottom. While I've been able to get the latter working, I haven't had much success with the former.
When the writing-mode is changed from top-to-bottom, the glyphs are rotated with the line of text. If you want to rotate the glyphs in any writing-mode you can use either glyph-orientation-horizontal or glyph-orientation-vertical, depending on the writing-mode being used.
Finally if you want to change where the EM box around a glyph is aligned you can set the text-anchor property to either start, middle, or end.
Next week I'll cover baseline alignment of SVG text.v
Writing SVG code once and being able to use it in multiple places helps you write more modular code and it helps make maintenance easier. SVG makes it easy to reuse text through the tref element.
Last week I walked you through the tspan element and showed how you could use it to style and position lines of text independent from one another. I presented some examples using the positioning attributes x, y, dx, and dy and mentioned there were a couple more attributes to look at.
Let's pick things up with the two remaining attributes and then I'll talk about reusing SVG text with the tref element. Please note that while the tref element is part of the SVG 1.1 spec, it’s being removed from the SVG 2.0 spec. I included in this series, in case you run across it somewhere.
The textLength and lengthAdjust Attributes
The two remaining attributes are textLength and lengthAdjust, and either or both can be added directly to any tspan.
As I've done with most of the examples in this series. I created an SVG element, defined the size of the viewport, and styled it so we can see an outline of the viewport and any text that renders outside of it. I also bumped up the font-size.
I positioned the two tspans so one sits below the other and styled the second with a red fill. I also added both textLength and lengthAdjust attributes to the <text> element. The text isn't stretched as you might expect.
However, adding the attributes to the first tspan does what you would expect. It stretches both the space and glyphs as the next example shows.
This suggests that unlike the rotate attribute, which we saw last week, textLength and lengthAdjust set on the text element don't propagate to the tspans.
One exception I found while playing around is if you add the textLength and/or lengthAdjust to the text element and haven't set x and y values for the first tspan, the textLength and lengthAdjust do seem to propagate.
I'm not sure if this is an error or the intended behavior, but I wanted to mention it in case it happens and you're wondering why.
In this example I added the text "hello" directly to the text element and before the first tspan and I added our two attributes directly on the text element. I also positioned the text element and since I didn't give any x or y coordinate to the first tspan it gets positioned just after the "hello" text.
The word "hello" is stretched as you would expect, but so is the SVG 1 text from the first tspan. It seems setting textLength and lengthAdjust stretch the line they're applied to regardless of which element they're set on.
If you take away the coordinates on the second tspan, it will also become part of the stretched line of SVG text.
Again I'm not sure if this is the expected behavior, a bug, or if I'm doing something wrong, but I thought I'd point it out in case you run across it.
The tref Element
Note: The tref element is part of the SVG 1.1 spec, but it’s being removed from the SVG 2.0 spec. What follows may or not work by the time you read this. I’ll be using images to show the results of the examples.
Earlier in the year during the previous round of this SVG series I showed how you could define SVG code in one location and then use and reuse it in other parts of your SVG document.
The tref element works the same way. It lets you define reference text inside a <defs> element and then reference it later. I'll refer you back to my post about <defs> if you need a reminder about how this works.
Or you can just follow along with the example in which I created a <text> element with SVG 1 inside and then I wrapped the <text> element with <defs> tags. Notice that I added an id of "referenced" to the <text> element.
To reference the text you use the xlink:href attribute inside a <tref> element where you want the text to appear.
Here I added the 1 and 2 on each tspan, but have the SVG text as a reference inside trefs in each. I also changed the id to referenced–2 so that it doesn't conflict with the previous example.
In these examples I placed the tref inside tspans, but the tref could also have been placed directly inside the text element. The referenced text will appear wherever the tref is added.
Closing Thoughts
If you understand how to work with <defs> and how to generally reuse SVG code, I'm guessing you won't have any problems working with the <tref> element either as it works the same way.
You define the text you want to reuse inside <defs> tags and then reference the text inside a <tref> element using the xlink:href attribute. It's more complicated to explain that to use.
There's still plenty more to cover in regards to SVG text. Over the next two week I'll talk about text layout features that are supported by SVG and show you some properties to help align SVG text in both the horizontal and vertical directions.
The SVG text element allows you to easily position and style text, but what do you do if you want to position and style different parts of the text differently? Do you need to create multiple text elements? Nope. There's an easier way.
The <text> element isn't the only element we can work with when working with SVG text, however. Today and next week I want to talk about two more SVG elements that you'll use in combination with the <text> element. I want to talk about the <tspan> and <tref> elements.
The tspan Element
You can think of the <tspan> element as a span for SVG text. You can wrap part or all of you SVG text inside a <tspan> to give you greater control over its display and to position different lines or snippets of text relative to each other.
Hopefully most of the code here is familiar to you after reading the previous two posts in this series. I created an <svg> element, defined the dimensions of the SVG viewport and added a red outline so we can see its boundaries. I also bumped up the font-size a bit and set the overflow to visible so we can see any text that displays outside of the viewport.
I positioned a text element at (240,120) and inside created two tspans, each containing the text "SVG" inside. Here's how it displays.
The text in the tspans displays inline one after the other, which is how they would have displayed directly inside the text element with a space between them.
Things get interesting once you know that the same attributes that are available to you on the <text> element are also available on the <tspan> element.
Let's change the position of the second tspan by setting its x and y coordinates. So we can tell the two tspans apart I added numbers to the text.
I moved the second tspan to a position (10,10). Because x and y are absolute positions, these values place SVG 2 just to the right of the left edge of the viewport and also about halfway above and below the top edge.
You might remember from the previous posts that the y position is the position of the baseline and not the top or bottom of the text.
For relative positioning we can use dx and dy as in the next example.
Here I styled SVG 2 to have a red fill instead of the default black. Again think of a tspan like you would a regular span, except that it's specifically used inside an SVG <text> element.
You can have one tspan display directly below another by giving both the same x value and giving the second one a dy value that positions it below the first.
Here I set the second tspan to have an x-coordinate equal to what was set on the text element and I gave it a dy value of 24 to drop it directly below the first tspan.
Note: I could have also set the position absolutely using y instead of dy.
Again all the attributes we saw last week for the text element can be used on the tspan. One thing to note is that any attribute set on the text element propagates to the tspans within it.
Here I rotated the text element 10 degrees and you can see that every character in both tspans has been rotated 10 degrees even though I didn't explicitly rotate either of the tspans.
That's probably not surprising, but what might be is, if you want to set the text in the first tspan back to normal, you don't set its rotation to –10 to compensate. Here's how that would look.
And now the text in the first tspan is once again upright.
There are a couple more attributes to get to as well as the tref element, but let's stop here and pick things up again next week.
Closing Thoughts
The SVG tspan element functions similarly to an ordinary HTML span element. By wrapping a tspan around part of the text you want to display, you can style and position that text independently of any text not in that tspan.
All the attributes available to the text element are also available to tspans as are fills and strokes and any of the attributes you can add to any SVG element.
The value of any attribute you add to a text element will propagate down to the tspans within it. If you don't want one to propagate, you set a new value on the tspan that overrides the value on the text element.
Next week, I'll continue with the textLength and lengthAdjust attributes and then I'll introduce the <tref> element which lets us reuse SVG text across different text and tspan elements.