Applying textLength to SVG tspan elements inline (horizontal)
I'm trying to do something that should be simple: display a word (an SVG text element) in which each character has a different colour. I did this programmatically: I split the string into characters, and inserted each character into a tspan element, each of which is inside a text element. I used the textLength attribute for spacing.
I tried so many permutations, but can't find a solution that works in all browsers.
Here's some code (just the SVG). Three examples, just to show how different browsers behave. The third one is what I want. It works in Chrome, but every other browser presents it differently:
<svg width = "250px" height = "100px">
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
// A regular text element:
<text y = "30px" textLength = "250px" fill = "hsl(120, 100%, 10%)">
greengradient
</text>
// A text element with tspan elements:
<text y = "60px">
<tspan textLength = "250px" fill = "hsl(120, 100%, 70%)">green</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 10%)">gradient</tspan>
</text>
// A text element with a tspan element for every character:
<text y = "90px">
<tspan textLength = "250px" fill = "hsl(120, 100%, 70%")>g</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 65%")>r</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 60%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 55%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 50%")>n</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 45%")>g</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 40%")>r</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 35%")>a</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 30%")>d</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 25%")>i</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 20%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 15%")>n</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 10%")>t</tspan>
</text>
</svg>Is there a browser-consistent way to apply textLength to inline tspan elements?
css svg
|
show 1 more comment
I'm trying to do something that should be simple: display a word (an SVG text element) in which each character has a different colour. I did this programmatically: I split the string into characters, and inserted each character into a tspan element, each of which is inside a text element. I used the textLength attribute for spacing.
I tried so many permutations, but can't find a solution that works in all browsers.
Here's some code (just the SVG). Three examples, just to show how different browsers behave. The third one is what I want. It works in Chrome, but every other browser presents it differently:
<svg width = "250px" height = "100px">
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
// A regular text element:
<text y = "30px" textLength = "250px" fill = "hsl(120, 100%, 10%)">
greengradient
</text>
// A text element with tspan elements:
<text y = "60px">
<tspan textLength = "250px" fill = "hsl(120, 100%, 70%)">green</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 10%)">gradient</tspan>
</text>
// A text element with a tspan element for every character:
<text y = "90px">
<tspan textLength = "250px" fill = "hsl(120, 100%, 70%")>g</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 65%")>r</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 60%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 55%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 50%")>n</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 45%")>g</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 40%")>r</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 35%")>a</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 30%")>d</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 25%")>i</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 20%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 15%")>n</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 10%")>t</tspan>
</text>
</svg>Is there a browser-consistent way to apply textLength to inline tspan elements?
css svg
1
I havn't got the time to do cross-browser testing right now, but I have two remarks I think you should take into account: 1. All whitespace inside a<text>element is rendered, even if they are outside<tspan>- so be sure they match between the variants. 2.textLengthis to be applied to just the element that should have the computed length, not to its children. In this case, it's always the<text>element, not the<tspan>. Additionally, atextLengthfor only one typographic character cannot be valid, because only advances between the first and last character can be adjusted.
– ccprog
Nov 26 '18 at 1:16
Thanks @ccprog. On point 2, I had thought that, too, yet it is only by applyingtextLengthto thetspanelements that it works in Chrome. I just tried your method (applying it only to thetextelement) and found it only works in Firefox when I do it that way! The reason I was applyingtextLengthto single characters was purely to fit them to space.
– Markus
Nov 26 '18 at 4:21
2
If you want to apply a gradient to the text why not just apply a linearGradient rather than colouring each letter?
– Robert Longson
Nov 26 '18 at 7:52
1
You should create a linear gradient like this:<linearGradient id="lg" > <stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop> <stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop> </linearGradient>and then fill the text:fill = "url(#lg)"
– enxaneta
Nov 26 '18 at 12:28
1
@Markus download the source code to Firefox and create a patch for bugzilla.mozilla.org/show_bug.cgi?id=890692
– Robert Longson
Nov 27 '18 at 10:17
|
show 1 more comment
I'm trying to do something that should be simple: display a word (an SVG text element) in which each character has a different colour. I did this programmatically: I split the string into characters, and inserted each character into a tspan element, each of which is inside a text element. I used the textLength attribute for spacing.
I tried so many permutations, but can't find a solution that works in all browsers.
Here's some code (just the SVG). Three examples, just to show how different browsers behave. The third one is what I want. It works in Chrome, but every other browser presents it differently:
<svg width = "250px" height = "100px">
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
// A regular text element:
<text y = "30px" textLength = "250px" fill = "hsl(120, 100%, 10%)">
greengradient
</text>
// A text element with tspan elements:
<text y = "60px">
<tspan textLength = "250px" fill = "hsl(120, 100%, 70%)">green</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 10%)">gradient</tspan>
</text>
// A text element with a tspan element for every character:
<text y = "90px">
<tspan textLength = "250px" fill = "hsl(120, 100%, 70%")>g</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 65%")>r</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 60%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 55%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 50%")>n</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 45%")>g</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 40%")>r</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 35%")>a</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 30%")>d</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 25%")>i</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 20%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 15%")>n</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 10%")>t</tspan>
</text>
</svg>Is there a browser-consistent way to apply textLength to inline tspan elements?
css svg
I'm trying to do something that should be simple: display a word (an SVG text element) in which each character has a different colour. I did this programmatically: I split the string into characters, and inserted each character into a tspan element, each of which is inside a text element. I used the textLength attribute for spacing.
I tried so many permutations, but can't find a solution that works in all browsers.
Here's some code (just the SVG). Three examples, just to show how different browsers behave. The third one is what I want. It works in Chrome, but every other browser presents it differently:
<svg width = "250px" height = "100px">
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
// A regular text element:
<text y = "30px" textLength = "250px" fill = "hsl(120, 100%, 10%)">
greengradient
</text>
// A text element with tspan elements:
<text y = "60px">
<tspan textLength = "250px" fill = "hsl(120, 100%, 70%)">green</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 10%)">gradient</tspan>
</text>
// A text element with a tspan element for every character:
<text y = "90px">
<tspan textLength = "250px" fill = "hsl(120, 100%, 70%")>g</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 65%")>r</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 60%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 55%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 50%")>n</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 45%")>g</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 40%")>r</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 35%")>a</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 30%")>d</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 25%")>i</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 20%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 15%")>n</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 10%")>t</tspan>
</text>
</svg>Is there a browser-consistent way to apply textLength to inline tspan elements?
<svg width = "250px" height = "100px">
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
// A regular text element:
<text y = "30px" textLength = "250px" fill = "hsl(120, 100%, 10%)">
greengradient
</text>
// A text element with tspan elements:
<text y = "60px">
<tspan textLength = "250px" fill = "hsl(120, 100%, 70%)">green</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 10%)">gradient</tspan>
</text>
// A text element with a tspan element for every character:
<text y = "90px">
<tspan textLength = "250px" fill = "hsl(120, 100%, 70%")>g</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 65%")>r</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 60%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 55%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 50%")>n</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 45%")>g</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 40%")>r</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 35%")>a</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 30%")>d</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 25%")>i</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 20%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 15%")>n</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 10%")>t</tspan>
</text>
</svg><svg width = "250px" height = "100px">
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
// A regular text element:
<text y = "30px" textLength = "250px" fill = "hsl(120, 100%, 10%)">
greengradient
</text>
// A text element with tspan elements:
<text y = "60px">
<tspan textLength = "250px" fill = "hsl(120, 100%, 70%)">green</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 10%)">gradient</tspan>
</text>
// A text element with a tspan element for every character:
<text y = "90px">
<tspan textLength = "250px" fill = "hsl(120, 100%, 70%")>g</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 65%")>r</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 60%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 55%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 50%")>n</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 45%")>g</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 40%")>r</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 35%")>a</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 30%")>d</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 25%")>i</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 20%")>e</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 15%")>n</tspan>
<tspan textLength = "250px" fill = "hsl(120, 100%, 10%")>t</tspan>
</text>
</svg>css svg
css svg
edited Nov 26 '18 at 4:26
Markus
asked Nov 25 '18 at 23:38
MarkusMarkus
13610
13610
1
I havn't got the time to do cross-browser testing right now, but I have two remarks I think you should take into account: 1. All whitespace inside a<text>element is rendered, even if they are outside<tspan>- so be sure they match between the variants. 2.textLengthis to be applied to just the element that should have the computed length, not to its children. In this case, it's always the<text>element, not the<tspan>. Additionally, atextLengthfor only one typographic character cannot be valid, because only advances between the first and last character can be adjusted.
– ccprog
Nov 26 '18 at 1:16
Thanks @ccprog. On point 2, I had thought that, too, yet it is only by applyingtextLengthto thetspanelements that it works in Chrome. I just tried your method (applying it only to thetextelement) and found it only works in Firefox when I do it that way! The reason I was applyingtextLengthto single characters was purely to fit them to space.
– Markus
Nov 26 '18 at 4:21
2
If you want to apply a gradient to the text why not just apply a linearGradient rather than colouring each letter?
– Robert Longson
Nov 26 '18 at 7:52
1
You should create a linear gradient like this:<linearGradient id="lg" > <stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop> <stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop> </linearGradient>and then fill the text:fill = "url(#lg)"
– enxaneta
Nov 26 '18 at 12:28
1
@Markus download the source code to Firefox and create a patch for bugzilla.mozilla.org/show_bug.cgi?id=890692
– Robert Longson
Nov 27 '18 at 10:17
|
show 1 more comment
1
I havn't got the time to do cross-browser testing right now, but I have two remarks I think you should take into account: 1. All whitespace inside a<text>element is rendered, even if they are outside<tspan>- so be sure they match between the variants. 2.textLengthis to be applied to just the element that should have the computed length, not to its children. In this case, it's always the<text>element, not the<tspan>. Additionally, atextLengthfor only one typographic character cannot be valid, because only advances between the first and last character can be adjusted.
– ccprog
Nov 26 '18 at 1:16
Thanks @ccprog. On point 2, I had thought that, too, yet it is only by applyingtextLengthto thetspanelements that it works in Chrome. I just tried your method (applying it only to thetextelement) and found it only works in Firefox when I do it that way! The reason I was applyingtextLengthto single characters was purely to fit them to space.
– Markus
Nov 26 '18 at 4:21
2
If you want to apply a gradient to the text why not just apply a linearGradient rather than colouring each letter?
– Robert Longson
Nov 26 '18 at 7:52
1
You should create a linear gradient like this:<linearGradient id="lg" > <stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop> <stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop> </linearGradient>and then fill the text:fill = "url(#lg)"
– enxaneta
Nov 26 '18 at 12:28
1
@Markus download the source code to Firefox and create a patch for bugzilla.mozilla.org/show_bug.cgi?id=890692
– Robert Longson
Nov 27 '18 at 10:17
1
1
I havn't got the time to do cross-browser testing right now, but I have two remarks I think you should take into account: 1. All whitespace inside a
<text> element is rendered, even if they are outside <tspan> - so be sure they match between the variants. 2. textLength is to be applied to just the element that should have the computed length, not to its children. In this case, it's always the <text> element, not the <tspan>. Additionally, a textLength for only one typographic character cannot be valid, because only advances between the first and last character can be adjusted.– ccprog
Nov 26 '18 at 1:16
I havn't got the time to do cross-browser testing right now, but I have two remarks I think you should take into account: 1. All whitespace inside a
<text> element is rendered, even if they are outside <tspan> - so be sure they match between the variants. 2. textLength is to be applied to just the element that should have the computed length, not to its children. In this case, it's always the <text> element, not the <tspan>. Additionally, a textLength for only one typographic character cannot be valid, because only advances between the first and last character can be adjusted.– ccprog
Nov 26 '18 at 1:16
Thanks @ccprog. On point 2, I had thought that, too, yet it is only by applying
textLength to the tspan elements that it works in Chrome. I just tried your method (applying it only to the text element) and found it only works in Firefox when I do it that way! The reason I was applying textLength to single characters was purely to fit them to space.– Markus
Nov 26 '18 at 4:21
Thanks @ccprog. On point 2, I had thought that, too, yet it is only by applying
textLength to the tspan elements that it works in Chrome. I just tried your method (applying it only to the text element) and found it only works in Firefox when I do it that way! The reason I was applying textLength to single characters was purely to fit them to space.– Markus
Nov 26 '18 at 4:21
2
2
If you want to apply a gradient to the text why not just apply a linearGradient rather than colouring each letter?
– Robert Longson
Nov 26 '18 at 7:52
If you want to apply a gradient to the text why not just apply a linearGradient rather than colouring each letter?
– Robert Longson
Nov 26 '18 at 7:52
1
1
You should create a linear gradient like this:
<linearGradient id="lg" > <stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop> <stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop> </linearGradient> and then fill the text: fill = "url(#lg)"– enxaneta
Nov 26 '18 at 12:28
You should create a linear gradient like this:
<linearGradient id="lg" > <stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop> <stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop> </linearGradient> and then fill the text: fill = "url(#lg)"– enxaneta
Nov 26 '18 at 12:28
1
1
@Markus download the source code to Firefox and create a patch for bugzilla.mozilla.org/show_bug.cgi?id=890692
– Robert Longson
Nov 27 '18 at 10:17
@Markus download the source code to Firefox and create a patch for bugzilla.mozilla.org/show_bug.cgi?id=890692
– Robert Longson
Nov 27 '18 at 10:17
|
show 1 more comment
1 Answer
1
active
oldest
votes
I'll answer (and end) this question, with thanks to Robert Longson and enxaneta.
After experimenting, there's no way to apply textLength to inline tspan elements consistently across browsers. The standard is still being developed. A few examples:
Firefox:

Chrome:

Edge:

The other question -- how to apply gradient colour to text elements -- is easier than my convoluted first attempt. Apply a linearGradient element to the SVG, then link it to the text element:
<svg width = "300px" height = "40px">
<linearGradient id="gradient">
<stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop>
<stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop>
</linearGradient>
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
<text y = "30px" textLength = "300px" fill = "url(#gradient)">
greengradient
</text>
</svg>add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53473104%2fapplying-textlength-to-svg-tspan-elements-inline-horizontal%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I'll answer (and end) this question, with thanks to Robert Longson and enxaneta.
After experimenting, there's no way to apply textLength to inline tspan elements consistently across browsers. The standard is still being developed. A few examples:
Firefox:

Chrome:

Edge:

The other question -- how to apply gradient colour to text elements -- is easier than my convoluted first attempt. Apply a linearGradient element to the SVG, then link it to the text element:
<svg width = "300px" height = "40px">
<linearGradient id="gradient">
<stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop>
<stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop>
</linearGradient>
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
<text y = "30px" textLength = "300px" fill = "url(#gradient)">
greengradient
</text>
</svg>add a comment |
I'll answer (and end) this question, with thanks to Robert Longson and enxaneta.
After experimenting, there's no way to apply textLength to inline tspan elements consistently across browsers. The standard is still being developed. A few examples:
Firefox:

Chrome:

Edge:

The other question -- how to apply gradient colour to text elements -- is easier than my convoluted first attempt. Apply a linearGradient element to the SVG, then link it to the text element:
<svg width = "300px" height = "40px">
<linearGradient id="gradient">
<stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop>
<stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop>
</linearGradient>
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
<text y = "30px" textLength = "300px" fill = "url(#gradient)">
greengradient
</text>
</svg>add a comment |
I'll answer (and end) this question, with thanks to Robert Longson and enxaneta.
After experimenting, there's no way to apply textLength to inline tspan elements consistently across browsers. The standard is still being developed. A few examples:
Firefox:

Chrome:

Edge:

The other question -- how to apply gradient colour to text elements -- is easier than my convoluted first attempt. Apply a linearGradient element to the SVG, then link it to the text element:
<svg width = "300px" height = "40px">
<linearGradient id="gradient">
<stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop>
<stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop>
</linearGradient>
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
<text y = "30px" textLength = "300px" fill = "url(#gradient)">
greengradient
</text>
</svg>I'll answer (and end) this question, with thanks to Robert Longson and enxaneta.
After experimenting, there's no way to apply textLength to inline tspan elements consistently across browsers. The standard is still being developed. A few examples:
Firefox:

Chrome:

Edge:

The other question -- how to apply gradient colour to text elements -- is easier than my convoluted first attempt. Apply a linearGradient element to the SVG, then link it to the text element:
<svg width = "300px" height = "40px">
<linearGradient id="gradient">
<stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop>
<stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop>
</linearGradient>
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
<text y = "30px" textLength = "300px" fill = "url(#gradient)">
greengradient
</text>
</svg><svg width = "300px" height = "40px">
<linearGradient id="gradient">
<stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop>
<stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop>
</linearGradient>
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
<text y = "30px" textLength = "300px" fill = "url(#gradient)">
greengradient
</text>
</svg><svg width = "300px" height = "40px">
<linearGradient id="gradient">
<stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop>
<stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop>
</linearGradient>
<style>
text {
font-size: 30px;
font-family: sans-serif;
font-weight: bold;
}
</style>
<text y = "30px" textLength = "300px" fill = "url(#gradient)">
greengradient
</text>
</svg>answered Nov 27 '18 at 10:47
MarkusMarkus
13610
13610
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53473104%2fapplying-textlength-to-svg-tspan-elements-inline-horizontal%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I havn't got the time to do cross-browser testing right now, but I have two remarks I think you should take into account: 1. All whitespace inside a
<text>element is rendered, even if they are outside<tspan>- so be sure they match between the variants. 2.textLengthis to be applied to just the element that should have the computed length, not to its children. In this case, it's always the<text>element, not the<tspan>. Additionally, atextLengthfor only one typographic character cannot be valid, because only advances between the first and last character can be adjusted.– ccprog
Nov 26 '18 at 1:16
Thanks @ccprog. On point 2, I had thought that, too, yet it is only by applying
textLengthto thetspanelements that it works in Chrome. I just tried your method (applying it only to thetextelement) and found it only works in Firefox when I do it that way! The reason I was applyingtextLengthto single characters was purely to fit them to space.– Markus
Nov 26 '18 at 4:21
2
If you want to apply a gradient to the text why not just apply a linearGradient rather than colouring each letter?
– Robert Longson
Nov 26 '18 at 7:52
1
You should create a linear gradient like this:
<linearGradient id="lg" > <stop offset="0%" stop-color="hsl(120, 100%, 70%)"></stop> <stop offset="100%" stop-color="hsl(120, 100%, 10%)"></stop> </linearGradient>and then fill the text:fill = "url(#lg)"– enxaneta
Nov 26 '18 at 12:28
1
@Markus download the source code to Firefox and create a patch for bugzilla.mozilla.org/show_bug.cgi?id=890692
– Robert Longson
Nov 27 '18 at 10:17