What's the difference between Dominant-baseline and Alignment-baseline? - svg

I've googled but got this:
https://codepen.io/felipe_matos/pen/pMrXpK
html, body, svg {
height: 200px;
}
text {
font: bold 8px Verdana, Helvetica, Arial, sans-serif;
}
.flex {
display: flex;
}
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dominant-baseline -->
<div class="flex">
<div>
<h2>Dominant-baseline</h2>
<svg viewBox="0 0 200 120" xmlns="http://www.w3.org/2000/svg">
<path d="M20,15 L180,15 M20,30 L180,30 M20,45 L180,45 M20,60 L180,60 M20,75 L180,75 M20,90 L180,90" stroke="grey" />
<text dominant-baseline="ideographic" x="30" y="30">Ideographic</text>
<text dominant-baseline="baseline" x="30" y="45">Baseline</text>
<text dominant-baseline="middle" x="30" y="60">Middle</text>
<text dominant-baseline="hanging" x="30" y="75">Hanging</text>
<text dominant-baseline="text-before-edge" x="30" y="90">text-before-edge</text>
<text dominant-baseline="text-after-edge" x="30" y="15">text-after-edge</text>
</svg>
</div>
<div>
<h2>Alignment-baseline</h2>
<svg viewBox="0 0 200 120" xmlns="http://www.w3.org/2000/svg">
<path d="M20,15 L180,15 M20,30 L180,30 M20,45 L180,45 M20,60 L180,60 M20,75 L180,75 M20,90 L180,90" stroke="grey" />
<text alignment-baseline="ideographic" x="30" y="30">Ideographic</text>
<text alignment-baseline="baseline" x="30" y="45">Baseline</text>
<text alignment-baseline="middle" x="30" y="60">Middle</text>
<text alignment-baseline="hanging" x="30" y="75">Hanging</text>
<text alignment-baseline="text-before-edge" x="30" y="90">text-before-edge</text>
<text alignment-baseline="text-after-edge" x="30" y="15">text-after-edge</text>
</svg>
</div>
</div>
it seems the two properties are exactly the same. Then why do we have two different types?

The distinction is that dominant-baseline is the baseline used to calculate the baseline table. Specifically the distinction will be found when you mix different fonts, for example, if you are using a roman font like English and quote something in an Indic Script, "অসমীয়া লিপিবাংলা লিপি". The baseline in the script is visible there, but it's different than the English baseline. Though in practice it tends to do the same thing probably because the distinction is pretty minor and involves building an adjustment table first vs. adjusting for the baseline.

Related

SVGs in menu getting cut off/cropped incorrectly

After spending hours looking into similar issues I still haven't found a solution that works. I have some SVGs that are rendering fine normally, but when they're placed in the <nav> parts are cut off. I have noticed that the issue seems to occur only when multiple SVG icons are used in the nav. So if, for example, I remove the first <li> item in its entirety the remaining SVGs seem to not have the problem of being cut off.
I've set up a codepen here with the same code below: https://codepen.io/lsg-alex/pen/oNgVLbq
<nav id="site-navigation" class="main-navigation">
<div class="menu-main-container">
<ul id="menu-main">
<li>
<a href="#"
><!--?xml version="1.0" encoding="UTF-8"?-->
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 12.1 18.1"
width="12.1"
height="18.1"
>
<defs>
<style>
.cls-1,
.cls-4 {
fill: none;
}
.cls-2 {
clip-path: url(#clip-path);
}
.cls-3 {
fill: #58585b;
}
.cls-4 {
stroke: #58585b;
stroke-linecap: square;
stroke-linejoin: round;
stroke-width: 0.5px;
}
</style>
<clipPath id="clip-path">
<rect class="cls-1" width="12.1" height="18.1"></rect>
</clipPath>
</defs>
<title>icon-archive</title>
<g id="Layer_2" data-name="Layer 2">
<g id="Layer_1-2" data-name="Layer 1">
<g class="cls-2">
<path
class="cls-3"
d="M7.85,17.05H1.05v-14h10v10.8M9,1.15v1.1H4.24Zm.35-.9-8.71,2H.61a.42.42,0,0,0-.36.4v14.8a.41.41,0,0,0,.4.4H8.29a.31.31,0,0,0,.24-.12l3.25-3.25a.39.39,0,0,0,.07-.31V2.65a.41.41,0,0,0-.4-.4H9.83V.65A.43.43,0,0,0,9.38.25Z"
></path>
<path
class="cls-4"
d="M7.85,17.05H1.05v-14h10v10.8M9,1.15v1.1H4.24Zm.35-.9-8.71,2H.61a.42.42,0,0,0-.36.4v14.8a.41.41,0,0,0,.4.4H8.29a.31.31,0,0,0,.24-.12l3.25-3.25a.39.39,0,0,0,.07-.31V2.65a.41.41,0,0,0-.4-.4H9.83V.65A.43.43,0,0,0,9.38.25Z"
></path>
</g>
</g>
</g>
</svg>
<span class="menu-item__text">Archive</span></a
>
</li>
<li>
<a href="#"
><!--?xml version="1.0" encoding="UTF-8"?-->
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 16.24 17.78"
width="16.24"
height="17.78"
>
<defs>
<style>
.cls-1 {
fill: none;
}
.cls-2 {
clip-path: url(#clip-path);
}
.cls-3 {
fill: #58585b;
}
</style>
<clipPath id="clip-path">
<rect class="cls-1" width="16.24" height="17.78"></rect>
</clipPath>
</defs>
<title>icon-topics</title>
<g id="Layer_2" data-name="Layer 2">
<g id="Layer_1-2" data-name="Layer 1">
<g class="cls-2">
<path
class="cls-3"
d="M5.24,10.35,6.23,8a.42.42,0,0,1,.39-.26h3.72a.44.44,0,0,1,.43.43.36.36,0,0,1-.06.2l-1,2.36a.42.42,0,0,1-.39.26H5.61a.44.44,0,0,1-.43-.43.36.36,0,0,1,.06-.2M8,.56,5.63,6.23a.43.43,0,0,1-.39.26H.61a.62.62,0,0,0,0,1.23H4.36a.43.43,0,0,1,.42.43.35.35,0,0,1,0,.2l-1,2.36a.42.42,0,0,1-.4.26H.61a.62.62,0,0,0,0,1.23H2.46a.43.43,0,0,1,.43.43.46.46,0,0,1-.05.2L1.11,16.93a.62.62,0,0,0,1.14.48l2.09-4.94a.42.42,0,0,1,.39-.26H8.44a.43.43,0,0,1,.43.43.46.46,0,0,1,0,.2L7.16,16.77a.62.62,0,0,0,1.15.46l2-4.76a.42.42,0,0,1,.39-.26h4.92a.6.6,0,0,0,.43-.18.61.61,0,0,0-.43-1h-4a.43.43,0,0,1-.42-.43.35.35,0,0,1,.05-.2l1-2.36a.42.42,0,0,1,.4-.26h3a.62.62,0,0,0,0-1.23H13.49a.43.43,0,0,1-.43-.43.46.46,0,0,1,0-.2l2.11-5A.62.62,0,0,0,14.08.38L11.61,6.23a.42.42,0,0,1-.39.26H7.51a.43.43,0,0,1-.43-.43.46.46,0,0,1,0-.2L9.18,1A.62.62,0,0,0,8,.56"
></path>
</g>
</g>
</g>
</svg>
<span class="menu-item__text">Topics</span></a
>
</li>
<li>
<a href="#"
><!--?xml version="1.0" encoding="UTF-8"?-->
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 16.72 16.14"
width="16.72"
height="16.14"
>
<defs>
<style>
.cls-1 {
fill: none;
}
.cls-2 {
clip-path: url(#clip-path);
}
.cls-3 {
fill: #58585b;
}
</style>
<clipPath id="clip-path" transform="translate(0 0)">
<rect class="cls-1" width="16.72" height="16.14"></rect>
</clipPath>
</defs>
<title>icon-search</title>
<g id="Layer_2" data-name="Layer 2">
<g id="Layer_1-2" data-name="Layer 1">
<g class="cls-2">
<path
class="cls-3"
d="M9.84,11c-2.75-.13-4.75-2.1-4.65-4.57A4.6,4.6,0,0,1,10,2.06a4.58,4.58,0,0,1,4.52,4.63A4.57,4.57,0,0,1,9.84,11m-5.55-.57c-.86.81-3,3-3.86,3.81a1,1,0,0,0-.15,1.5,1.07,1.07,0,0,0,1.6,0c.87-.82,3.05-3.08,3.89-3.89,4.1,2.38,7.81,1,9.71-1.56a6.37,6.37,0,0,0-.8-8.44,7,7,0,0,0-9.06-.47,6.43,6.43,0,0,0-1.33,9"
transform="translate(0 0)"
></path>
</g>
</g>
</g>
</svg>
<span class="menu-item__text">Search</span></a
>
</li>
</ul>
</div>
</nav>
I tried adjusting the viewBox settings, height/width on the SVGs themselves as well as through CSS, setting overflow to visible, using a .svg inside an tag, etc. but none of these seem to have any impact. When I pull one of the SVGs that's cut off outside of the nav and paste the code above it, for example, it renders properly.
I can't help but feel like there's something obvious here I'm overlooking, and any help would be really appreciated.
This line is your culprit, remove them (or at least this first one since it's the one effecting the ones below it) and voila;
<clipPath id="clip-path">
<rect class="cls-1" width="12.1" height="18.1"></rect>
</clipPath>
Then to keep it clean, remove the references to it in the CSS such as;
clip-path: url(#clip-path);
I'm going to assume these were generated with something and you didn't intend on needing a specified clip-path anyway.
Cheers!

Using textLength attribute

I have segments of text that I want to put into a fixed 80px width, and I'm looking for the best way to implement fall-back if they don't quite fit (they will all be very close so I expect spacing can be used to make corrections).
I looked at the documentation for the textLength attribute but found it very hard to understand -- and the examples don't help at all. Specifying the pixel width on a text element garbles the text in Firefox and does nothing in my Chrome.
An article at More Robust SVG Text gave examples in 'em' units, but I haven't found any official documentation to explain why that works when pixels do not. Using that method helps in Firefox (although it's ignored on tspan), but is totally ignored in Chrome.
<svg width="570px" height="310px" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<style>
text {
text-anchor: middle;
font-size: 13px;
font-weight: bold;
font-family: "Times New Roman";
}
</style>
<rect x="115" y="180" width="80" height="80" fill="white" stroke="black"/>
<text x="155" y="180" textLength="80">
<tspan dy="1.2em" x="155" >Elizabeth</tspan>
<tspan dy="1.1em" x="155" >Taylor</tspan>
<tspan dy="1.1em" x="155" >(c1731–1783)</tspan>
</text>
</svg>
Can someone explain how to use it in a portable way?
The problem is that the behaviour of textLength when there are <tspan> elements is a little buggy on all(?) browsers.
Firefox's behaviour is correct I think, and makes sense if you leave all the <tspan> elements in their default position, and don't move them.
(View this in Firefox)
<svg width="570px" height="310px" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<style>
text {
text-anchor: middle;
font-size: 13px;
font-weight: bold;
font-family: "Times New Roman";
}
</style>
<rect x="115" y="180" width="80" height="80" fill="white" stroke="black"/>
<text x="155" y="180" textLength="80">
<tspan dy="1.2em" x="155" >Elizabeth</tspan>
<tspan dy="1.1em" x="155" >Taylor</tspan>
<tspan dy="1.1em" x="155">(c1731–1783)</tspan>
</text>
<text x="155" y="180" textLength="80">
<tspan>Elizabeth</tspan>
<tspan>Taylor</tspan>
<tspan>(c1731–1783)</tspan>
</text>
</svg>
It is resizing all the text so that its total length is 80px.
Perhaps you wanted each <tspan> to be length 80px? You don't say. The reason that isn't happening is because textLength is not a style property. Thus it isn't inherited by the <tspan> elements. If you want that, you have to set that attribute on every <tspan>.
<svg width="570px" height="310px" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<style>
text {
text-anchor: middle;
font-size: 13px;
font-weight: bold;
font-family: "Times New Roman";
}
</style>
<rect x="115" y="180" width="80" height="80" fill="white" stroke="black"/>
<text x="155" y="180">
<tspan dy="1.2em" x="155" textLength="80">Elizabeth</tspan>
<tspan dy="1.1em" x="155" textLength="80">Taylor</tspan>
<tspan dy="1.1em" x="155" textLength="80">(c1731–1783)</tspan>
</text>
</svg>
Unfortunately, this only works on Chrome currently, but not on Firefox.
Basically it seems that Chrome only likes textLength when it is on a leaf child element. And Firefox only likes it when it is on a parent text element.
You don't say exactly what you want, but my recommendation would be to avoid <tspan> and use proper <text> elements for every line, if you want the behaviour to match on all browsers.
(The following example looks the same on Chrome and Firefox)
<svg width="570px" height="310px" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<style>
text {
text-anchor: middle;
font-size: 13px;
font-weight: bold;
font-family: "Times New Roman";
}
</style>
<rect x="115" y="180" width="80" height="80" fill="white" stroke="black"/>
<text x="155" y="180" dy="1.2em" textLength="80">Elizabeth</text>
<text x="155" y="180" dy="2.3em" textLength="80">Taylor</text>
<text x="155" y="180" dy="3.4em" textLength="80">(c1731–1783)</text>
</svg>

why text-outline not work in my svg?

whenever i use text-outline or stroke in style. it's not work. how i can give text-outline to my text(SVG TEXT) in text tag.
<div class="slides2">
<img class="" src="//cdn.shopify.com/s/files/1/0797/1743/products/HK-CK_28785899-10b3-4f49-88be-975a69089e52_1024x1024.JPG?v=1464803870">
<div class="custom">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="410" height="70" viewBox="0 0 2326 460">
<defs>
<clipPath id="my-path">
<text id="texty" style="font-weight:bold;text-outline: 2px 2px #ff0000;" x="60" y="300" font-size="350">SVG TEXT</text>
</clipPath>
</defs>
<image xlink:href="Mother of Pearl.JPG" clip-path="url(#my-path)" width="100%" height="100%" id="filler" preserveAspectRatio="none"></image>
</svg>
</div>
</div>
Anything you include in a <clipPath> is used only to form the clipping path. It is never rendered.
If you want it to also be rendered, then you will need to include it again as a separate object.
<div class="slides2">
<img class="" src="//cdn.shopify.com/s/files/1/0797/1743/products/HK-CK_28785899-10b3-4f49-88be-975a69089e52_1024x1024.JPG?v=1464803870">
<div class="custom">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="410" height="70" viewBox="0 0 2326 460">
<defs>
<clipPath id="my-path">
<text id="texty" style="font-weight:bold;" x="60" y="300" font-size="350">SVG TEXT</text>
</clipPath>
</defs>
<image xlink:href="Mother of Pearl.JPG" clip-path="url(#my-path)" width="100%" height="100%" id="filler" preserveAspectRatio="none"></image>
<text id="texty" style="font-weight:bold; stroke: #f00; stroke-width: 2;" x="60" y="300" font-size="350">SVG TEXT</text>
</svg>
</div>
</div>

How to make JAWS read texts in a SVG graph in a significant order

I was trying to add accessibility to my chart based on SVG. I added id and aria-labelledby attributes to map the labels and values:
<svg width="400" height="200" tabindex="0">
<g class="subjects">
<text id="subject1">Maths</text>
<text id="subject2">Physics</text>
<text id="subject3">English</text>
<text id="subject4">Chemistry</text>
</g>
<g class="marks">
<text aria-labelledby="subject1">90%</text>
<text aria-labelledby="subject2">85%</text>
<text aria-labelledby="subject3">80%</text>
<text aria-labelledby="subject4">95%</text>
</g>
</svg>
But the screen reader (JAWS) is reading out in sequence:
Maths Physics English Chemistry 90% 85% 80% 95%
I want the screen reader to read:
Maths 90% Physics 85% English 80% Chemistry 95%
So firstly let me say that SVG accessibility is an emerging area of accessibility and so these techniques may only work on a subset of browsers), that having been said, you could get better accessibility now on the supporting browsers by doing this (caveat - tested only on OS X with Safari):
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="400px" height="200px" viewBox="0 0 400 200" tabindex="0">
<g class="subjects">
<text y="25" aria-label="Maths 90%">Maths</text>
<text y="75" aria-label="Physics 85%">Physics</text>
<text y="125" aria-label="English 80%">English</text>
<text y="175" aria-label="Chemistry 95%">Chemistry</text>
</g>
<g class="marks" aria-hidden="true">
<text x="100" y="25">90%</text>
<text x="100" y="75">85%</text>
<text x="100" y="125">80%</text>
<text x="100" y="175">95%</text>
</g>
</svg>
The following will work on more browsers e.g. IE on Windows and Safari on OS X
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="400px" height="200px" viewBox="0 0 400 200" tabindex="0" aria-labelledby="svgDesc">
<title id="svgDesc">
Maths 90%, Physics 85%, English 80%, Chemistry 95%
</title>
<g class="subjects" aria-hidden="true">
<text y="25">Maths</text>
<text y="75">Physics</text>
<text y="125">English</text>
<text y="175">Chemistry</text>
</g>
<g class="marks" aria-hidden="true">
<text x="100" y="25">90%</text>
<text x="100" y="75">85%</text>
<text x="100" y="125">80%</text>
<text x="100" y="175">95%</text>
</g>
</svg>
In order to get something to work everywhere as of the writing of this answer, you have to rely on essentially treating the SVG as an image and providing an alternative as a text description as shown above in the second example, or hiding the entire thing with aria-hidden="true" and providing an "off-screen" alternative such as a table or alternative HTML presentation. The example below will work everywhere for and provide real semantic markup that equals the visual display.
<!doctype html>
<html>
<head>
<style>
.screen-reader-text {
position: absolute !important;
height: 1px; width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
clip-path: polygon(0px 0px, 0px 0px,0px 0px, 0px 0px);
}
</style>
</head>
<body>
<table class="screen-reader-text">
<tr>
<th scope="col">Subject</th>
<th scope="col">Percentage</th>
</tr>
<tr>
<th scope="row">Maths</th>
<td scope="col">90%</td>
</tr>
<tr>
<th scope="row">Physics</th>
<td scope="col">85%</td>
</tr>
<tr>
<th scope="row">English</th>
<td scope="col">80%</td>
</tr>
<tr>
<th scope="row">Chemistry</th>
<td scope="col">95%</td>
</tr>
</table>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="400px" height="200px" viewBox="0 0 400 200" aria-hidden="true">
<g class="subjects">
<text y="25">Maths</text>
<text y="75">Physics</text>
<text y="125">English</text>
<text y="175">Chemistry</text>
</g>
<g class="marks">
<text x="100" y="25">90%</text>
<text x="100" y="75">85%</text>
<text x="100" y="125">80%</text>
<text x="100" y="175">95%</text>
</g>
</svg>
</body>
</html>
Maybe exploit the fact that "labelledby" will accept multiple ids. added roles and title element. This seems to read as desired:
<svg width="400" height="200" tabindex="0" role="img"
aria-labelledby="chart-title subject1 val1 subject2 val2 subject3 val3 subject4 val4">
<title id="chart-title">Student's grades for quarter:</title>
<g class="subjects" role="presentation">
<text id="subject1">Maths</text>
<text id="subject2">Physics</text>
<text id="subject3">English</text>
<text id="subject4">Chemistry</text>
</g>
<g id="marks" role="presentation">
<text id="val1">90%</text>
<text id="val2">85%</text>
<text id="val3">80%</text>
<text id="val4">95%</text>
</g>
</svg>

Consistently change background colour upon hovering over an SVG link

I decided to play around re-making a nav menu in SVG. It looks quite a bit like this site's nav actually, so nothing much to imagine.
I'm drawing boxes with SVG and then placing text over them, enclosing them both in a link. By attaching a css class to the box, I can set a :hover attritbute, so I can change the background colour when the user hovers over it. The problem is, when the user hovers over the text the color change is reversed, even though the link still works.
How can I make the box change colour as well?
The code looks like this:
<svg width="640px" height="40px"
xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(60 20) ">
<a xlink:href="http://www.apple.com">
<rect width="100" height="40" x="-50" y="-20" rx="5" class="svg_nav" />
<text class= "nav_text" text-anchor="middle" dominant-baseline="mathematical">Home</text>
</a>
</g>
</svg>
What do your style rules look like?
Something like the following should work fine:
<svg width="640px" height="40px"
xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(60 20) ">
<a xlink:href="http://www.apple.com">
<rect width="100" height="40" x="-50" y="-20" rx="5" class="svg_nav" />
<text class= "nav_text" text-anchor="middle" dominant-baseline="mathematical">Home</text>
</a>
</g>
<g transform="translate(166 20) ">
<a xlink:href="http://www.apple.com">
<rect width="100" height="40" x="-50" y="-20" rx="5" class="svg_nav" />
<text class= "nav_text" text-anchor="middle" dominant-baseline="mathematical">Home</text>
</a>
</g>
<style>
g:hover .svg_nav { fill: blue }
g:hover .nav_text { fill: red }
.svg_nav { fill: yellow }
.nav_text { fill: black }
</style>
</svg>

Resources