Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG focusable attribute is not working

I used focusable attribute to force SVG elements get focus in HTML document.

I need to navigate in SVG elements in SVG tag by TAB key. Like mentioned in the document (http://www.w3.org/TR/SVGTiny12/interact.html#focusable-attr)

But I cannot do it. I have set the focusable attribute to true, and tabindex of each element to 0.

Here is my code:

<div style="border: solid yellow 2px;" tabindex="0">
<svg tabindex="0" width="900px" height="500px" viewBox="0 0 95 50" style="border: solid red 1px;" focusable="true"
     xmlns="http://www.w3.org/2000/svg">
    <g data-Name="group" tabindex="0" stroke="green" fill="white" stroke-width="5" data-tabindex="0" style="border: solid green 1px;" focusable="true">
        <circle tabindex="0" cx="20" cy="25" r="5" focusable="true" data-Name="shape 1"  data-tabindex="0" />
        <circle tabindex="0" cx="40" cy="25" r="5" focusable="true" data-Name="shape 2"  data-tabindex="0" />
        <circle tabindex="0" cx="60" cy="25" r="5" focusable="true" data-Name="shape 3" data-tabindex="0" />
        <circle tabindex="0" cx="80" cy="25" r="5" focusable="true" data-Name="shape 4" data-tabindex="0" />
    </g>
</svg>

I have tested the code in Google Chrome. Is there any way to reach purpose?

like image 436
farid bekran Avatar asked Mar 26 '14 19:03

farid bekran


2 Answers

As @Robert Longson mentioned in the comments, SVG 1.2 was never finalized and SVG 1.2 Tiny is not implemented by web browsers. SVG 2 will have a tabIndex attribute, with the same purpose as in HTML, but there are still some details to work out and many browsers have not implemented it yet (Chrome, IE and Firefox do respect tabIndex on SVG elements in HTML pages).

In the meantime, however, most browsers will allow <a> link elements in SVG to get keyboard focus if they have an xlink:href attribute (even if it is a no-op link like #). You cannot control the tab order, or control focus from scripts, but you can allow users to cycle through elements, and the link will receive user input events.

The following snippet changes the styling of your circles when the link that contains them gets the user focus.

svg {
  max-height: 100vh;
  max-width: 100vw;
  }

a:focus {
  fill: blue;
  fill-opacity: 0.5;
  outline: none;
}
<svg width="900px" height="500px" viewBox="0 0 95 50" style="border: solid red 1px;"
     xmlns="http://www.w3.org/2000/svg">
    <g data-Name="group" stroke="green" fill="white" stroke-width="5" data-tabindex="0" >
      <a xlink:href="#">
        <circle cx="20" cy="25" r="5" data-Name="shape 1"  data-tabindex="0" />
      </a>
      <a xlink:href="#">
        <circle cx="40" cy="25" r="5" data-Name="shape 2"  data-tabindex="0" />
      </a>
      <a xlink:href="#">
        <circle cx="60" cy="25" r="5" data-Name="shape 3" data-tabindex="0" />
      </a>
      <a xlink:href="#">
        <circle cx="80" cy="25" r="5" data-Name="shape 4" data-tabindex="0" />
      </a>
    </g>
</svg>
like image 82
AmeliaBR Avatar answered Oct 14 '22 15:10

AmeliaBR



I was searching for a solution to navigate inside SVG for a while now, my intention is to have some SVG elements and navigate from one to another.
A good solution is this library: https://github.com/flesler/jquery.scrollTo/releases My code that navigates from a node to another node is(navigates from yellow circle to red one):

<html>
<head>
<link type="text/css" rel="stylesheet" href="css/style.css" />
	<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
	<script type="text/javascript" src="./js/jquery.scrollTo.min.js"></script>
	<script type="text/javascript" src="./js/jquery.localScroll.js"></script>
	<script type="text/javascript">
		jQuery(function( $ ){
			/**
			 * Most jQuery.localScroll's settings, actually belong to jQuery.ScrollTo, check it's demo for an example of each option.
			 * @see http://demos.flesler.com/jquery/scrollTo/
			 * You can use EVERY single setting of jQuery.ScrollTo, in the settings hash you send to jQuery.localScroll.
			 */
			
			// The default axis is 'y', but in this demo, I want to scroll both
			// You can modify any default like this
			$.localScroll.defaults.axis = 'xy';
			
			$.localScroll({
				//target: '#content', // could be a selector or a jQuery object too.
				queue:true,
				duration:1000,
				hash:true,
				lazy:true,
				onBefore:function( e, anchor, $target ){
					// The 'this' is the settings object, can be modified
				},
				onAfter:function( anchor, settings ){
					// The 'this' contains the scrolled element (#content)
				}
			});
			
			$('#nodeX').click(function() {
				$('html, body').scrollTo(document.getElementById('node1'), 1000);
			});
		});

</script>
</head>
<body>

<svg id="panel" width="3249pt" height="2200pt" viewBox="0.00 0.00 3249.00 2200.00" >

<g id="nodeX">
 <a xlink:href="#node1">
	<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
 </a>
 </g>

 <g id="node1">
 <circle cx="1880" cy="1580" r="40" stroke="green" stroke-width="4" fill="red" />
 </g>
 
</svg>

</body>
like image 30
Lucian Avatar answered Oct 14 '22 16:10

Lucian