I am trying to attach a file in chat box by clicking on attach icon, which is a svg element. Below is the HTML :
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" style="height: 100%; width: 100%;">
<path class="icon-attach_svg__fill" d="M55.334 28.926l-24.506 23.34c-5.222 4.973-13.74 4.973-18.962 0-5.149-4.903-5.149-12.797 0-17.7l24.506-23.34c3.138-2.988 8.278-2.988 11.416 0 3.064 2.919 3.064 7.594 0 10.513L23.255 45.077c-1.055 1.005-2.815 1.005-3.87.001-.98-.933-.98-2.39 0-3.325l22.64-21.535a2.667 2.667 0 00-3.676-3.864L15.709 37.89a7.578 7.578 0 00-.001 11.05c3.113 2.966 8.11 2.966 11.224 0l24.533-23.338c5.272-5.021 5.272-13.217 0-18.238-5.197-4.95-13.573-4.95-18.77 0L8.187 30.704c-7.356 7.005-7.356 18.419 0 25.424 7.281 6.935 19.036 6.935 26.318 0l24.506-23.34a2.666 2.666 0 10-3.678-3.862z" fill="#000" fill-rule="evenodd"></path></svg>
I am using below code to get element and attach file.
cy.xpath("//*[name()='path' and contains(#class,'icon-attac')]").attachFile("Automation.pdf")
Interestingly, Cypress passes this test but attached file is not displayed in UI.
I tried manually and checked. The file is displayed in UI, but while automating using cypress it is not present.
Is there any other way to handle svg element for attachFile ?
Related
I have a Gatsby project, where where I would like to use an svg as my main heading.
import Header from "../images/header.svg"
return (
<h1>
<Header/>
</h1>
)
Thers is no text in the svg (the text is made purely using rects and paths), so what do I do in terms of accessibility and SEO optimization?
Two ways to address this, visually hidden text or by adding a <title> to your SVG.
Do not use aria-label as support is not great (you will see people recommending that for SVGs, aria-label does not tend to work well on static / non-interactive elements).
Visually Hidden text (screen reader only text)
Visually hidden text is not visible on the screen but will still be read by a screen reader.
Please use the CSS class below to visually hide text, it has better compatibility and is future proofed compared to most current "screen reader only" classes as explained in this answer I gave
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
<h1>
<span class="visually-hidden">Welcome To Our Site</span>
<svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
<path fill="#666" d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z">
</path>
</svg>
</h1>
important: notice how I add focusable="false" as well as aria-hidden="true" to the SVG, this is to fix a bug with Internet Explorer where SVGs are focusable and to hide the SVG from screen readers. I used a youtube icon to represent your text as that was the closest SVG I had to hand!
Add a <title> element to your SVG.
The <title> element is effectively the same as alt on a normal image. Using this gives the screen reader something to announce.
Obviously you would then remove the aria-hidden="true" from it so it can be read by a screen reader!
Update after comments to include best practices for <title> and or <desc>
Thanks to the comments I realised this answer was lacking some key information on how to correctly use a <title>.
In this answer I gave I referenced a series of tests by deque which show that the most reliable method for labelling an SVG for screen readers using WAI-ARIA was to use aria-labelledby and point that to the <title> (and <desc> if you have both).
So a rough idea of how to do this is as follows:
<h1>
<svg aria-labelledby="welcome-title" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
<title id="welcome-title">Welcome To Our Site</title>
<path fill="#666" d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z">
</path>
</svg>
</h1>
Which is better?
Go for visually hidden text.
It works all the way back to IE6 which predates SVG!
It also works in a text only browser (one that does not understand CSS) as it will still be displayed. It is an edge case but still a win for visually hidden text!
How would I be able to convert this type of svg:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="250" height="250" viewBox="0 0 250 250">
<metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c145 79.163499, 2018/08/13-16:40:22 ">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/">
<xmpRights:Marked>True</xmpRights:Marked>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?></metadata>
<image id="N_side_slit" data-name="N side slit" x="21" y="44" width="178" height="148" xlink:href="data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAALIAAACUCAYAAAA3f3NDAAADx0lEQVR4nO3a3Y3rNhCA0dm9eUtTaSA9pIX0ky5SQFJCmslj4GCBXcAw1j+SSHGGPN+zJdP0sSCTertcLpeo2VvRcc/eEE/vhUFU/QGqQ++fp4RZpXu/GjzMKtv7zcBhVsluIQfMqth3kANmVese5IBZlXoEOWBWlZ5BDphVoVcgB8zK3quQA2ZlbgvkgFlZ2wo5YFbG9kAOmJWtvZDjE/M/BXHAPGFHIH/0e0T8C7NGdxTy3xHxK8wa3VHIAbMy1AJywKzRtYIcMGtkLSEHzBpVa8gBs0bUA3LArLPrBTlg1pn1hBww66x6Qw6YdUZnQA6Y1buzIAfM6tmZkANm9epsyAGzejQCcsCs1o2CHDCrZSMhB8xq1WjIAbNalAFywKyjZYEcMOtImSAHzNpbNsgBs/aUEXLArK1lhRwwa0uZIQfMerXskANmvVIFyAGznjUS8m8bXw+z7jYS8h8wq1UjIf+AWa0afY8Ms5qU4c8ezDpcllULmHWoTMtvMGt32daRYdauMm6IwKzNZd3Zg1mbyrxFDbNeLvuzFjDrpSo8NASznlbl6TeY9bAqkANmPaoS5IBZ96oGOWDWd1WEHDDrtqqQA2ZdVxlywKyvqkMOmBWTQA6YNQvkgHntZoIcMK/bbJAD5jWbEXLAvF6zQg6Y12pmyAHzOs0OOWBeoxUgB8zz93a5DPu8I974v4j4acdxv0TEnxHx88ecdRhXz84e7xBQq1yRv/qx8zhX5uStBvlIMCcO5G3BnDSQtwdzwkDeF8zJAnl/MCcK5GNdY67WVJhXW0eOTuuqH+vMf3U47xm1no8h3yvIbat6lWs5JzZEJqjart9X5W8zQG4fzAMCuU8wnxzI/YL5xEDuG8wnBXL/YD4hkM8J5s6BfF4wdwzkc4O5UyCfH8wdAnlMMDcO5HHB3DCQxwZzo0AeH8wNAjlHMB8M5DzBfCCQcwXzzkDOF8w7AjlnMG8M5LxVxTwkkHMH84uBnD+YXwjkGsH8JJDrBPODQK4VzHcCuV4wfxPINYP5JpDrBvNVINcO5s9Art/ymAPkaVoeM8jztDRmkOdqWcwgz9eSmEGes+UwgzxvS2EGee6WwQzy/C2BGeQ1mh4zyOs0NWaQ12pazCCv15SYQV6z6TCDvG5TYQZ57abBDLKmwAyyYgbMIOur0phB1nVlMYOs20piBlnfVQ4zyLpXKcwg61FlMIOsZ5XADLJeKT1mkPVqqTGDrC2lxQyytpYSM8jaUzrMIGtvqTCDrCOlwQyyjpYCM8hq0XDMIKtV4zBHxP/bUFzI1KMfEAAAAABJRU5ErkJggg=="/>
</svg>
To a type of svg that has a path and is usable in html like this:
<svg width="36px" height="24px" viewBox="0 0 36 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M8.98885921,23.8523026 C8.8942483,23.9435442 8.76801031,24 8.62933774,24 L2.03198365,24 C1.73814918,24 1.5,23.7482301 1.5,23.4380086 C1.5,23.2831829 1.55946972,23.1428989 1.65570253,23.0416777 L13.2166154,12.4291351 C13.3325814,12.3262031 13.4061076,12.1719477 13.4061076,11.999444 C13.4061076,11.8363496 13.3401502,11.6897927 13.2352673,11.587431 L1.68841087,0.990000249 C1.57298556,0.88706828 1.5,0.733668282 1.5,0.561734827 C1.5,0.251798399 1.73814918,2.85130108e-05 2.03198365,2.85130108e-05 L8.62933774,2.85130108e-05 C8.76855094,2.85130108e-05 8.89532956,0.0561991444 8.98994048,0.148296169 L21.4358709,11.5757407 C21.548593,11.6783875 21.6196864,11.8297916 21.6196864,11.999444 C21.6196864,12.1693815 21.5483227,12.3219261 21.4350599,12.4251432 L8.98885921,23.8523026 Z M26.5774333,23.8384453 L20.1765996,17.9616286 C20.060093,17.8578413 19.9865669,17.703871 19.9865669,17.5310822 C19.9865669,17.3859509 20.0390083,17.2536506 20.1246988,17.153855 L23.4190508,14.1291948 C23.5163648,14.0165684 23.6569296,13.945571 23.8131728,13.945571 C23.9602252,13.945571 24.0929508,14.0082997 24.1894539,14.1092357 L33.861933,22.9913237 C33.9892522,23.0939706 34.0714286,23.2559245 34.0714286,23.4381226 C34.0714286,23.748059 33.8332794,23.9998289 33.5394449,23.9998289 L26.9504707,23.9998289 C26.8053105,23.9998289 26.6733958,23.9382408 26.5774333,23.8384453 Z M26.5774333,0.161098511 C26.6733958,0.0615881034 26.8053105,0 26.9504707,0 L33.5394449,0 C33.8332794,0 34.0714286,0.251769886 34.0714286,0.561706314 C34.0714286,0.743904453 33.9892522,0.905573224 33.861933,1.00822006 L24.1894539,9.89030807 C24.0929508,9.99152926 23.9602252,10.0542579 23.8131728,10.0542579 C23.6569296,10.0542579 23.5163648,9.98354562 23.4190508,9.87063409 L20.1246988,6.8459739 C20.0390083,6.74617837 19.9865669,6.613878 19.9865669,6.46874677 C19.9865669,6.29624305 20.060093,6.14198767 20.1765996,6.03848544 L26.5774333,0.161098511 Z" fill="#FFFFFF"></path>
</svg>
(These are 2 different images)
You'll need to load the first one into a vector editor (eg Inkscape) and use the editor's drawing tools to manually recreate the shape(s).
After 2-3 hours of messing with every possible online program. I downloaded Inkscape and tried to make a svg.
It took another 2 hours because it was showing 0 path every time I was trying to make a svg. Then I found out it didn't detect the shape because it was white.
So I had to go back to photoshop, change the colour to black, save as a PNG then open it on Inkscape then re-path it. Took me way to long to figure this out.
You will need a thirdparty program to make svgs, there is no escaping them. I tried.
Thank you Paul for the suggestion.
The goal is to create multiple buttons (in my case two) with different symbols based on one SVG.
I have an SVG file containing 3 groups with vector shapes.
One group is background that needs to be filled by particular color (hover).
Two other groups contain different symbols (ellipse,square) and named with ZZZ at the end.
One button should show ellipse, another button-square.
I've set these two groups in SVG to "display:none" unless they are targeted.Content of the test.svg as follow:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22"><defs><style>
.cls-1 {
fill: #340000;
}
.cls-2 {
fill: none;
stroke: #fff;
stroke-miterlimit: 10;
}
[id$=zzz] { display: none; }
g:target { display: block; }
</style></defs><g id="Layer_2" data-name="Layer 2"><g id="test"><g id="group_background" data-name="group background"><rect id="shape_background" data-name="shape background" class="cls-1" width="22" height="22"/></g><g id="square_zzz" data-name="square zzz"><rect id="shape_square" data-name="shape square" class="cls-2" x="4.731" y="4.237" width="13.119"height="13.119"/>
</g>
<g id="ellipse_zzz" data-name="ellipse zzz">
<circle id="shape_ellipse" data-name="shape ellipse" class="cls-2" cx="11.29" cy="10.797" r="6.693"/>
</g></g></g></svg>
In my CSS I'm trying to show different shapes on the buttons:
.button1{background-image:url(test.svg#square_zzz);}.button2{background-image:url(test.svg#ellipse_zzz);}
However nothing shows up.
Question dismissed. Targeting ID works fine - ( Dreamweaver Live view issue).
Still trying to figure out how to change color for background and shape on targeting group with CSS and implement cloneNode() to duplicate button without creating multiple SVG instances for each button.
So, I'm trying to create an ERD tool using JointJS and would like to create a custom link with markup something like
<path><rect><path>
The idea is to have a rhombus in the middle of the link, I know I can do this with a an Element and two links, but I really want to be able to have some custom markup in the link. Can this be done? If so, how?
You can have your own markup for links, just like for other elements. However, the supplied Link markup code is pretty complex, compared with that of, say, a Rect. In joint.js:
joint.dia.Link = joint.dia.Cell.extend({
// The default markup for links.
markup: [
'<path class="connection" stroke="black" d="M 0 0 0 0"/>',
'<path class="marker-source" fill="black" stroke="black" d="M 0 0 0 0"/>',
'<path class="marker-target" fill="black" stroke="black" d="M 0 0 0 0"/>',
'<path class="connection-wrap" d="M 0 0 0 0"/>',
'<g class="labels"/>',
'<g class="marker-vertices"/>',
'<g class="marker-arrowheads"/>',
'<g class="link-tools"/>'
].join(''),
As you can see, unlike a Rect a Link is really made up of several objects. And that's just for the Link; there is also markup for labels, vertices, etc., and you might have to take those into account, depending on your requirements.
In my case, I am adding a tooltip --- HTML <title> element --- to elements. For a Rect I simply hard-coded:
markup: '<g class="rotatable"><g class="scalable"><rect/></g><text/><title/></g>'
but for Links I elected to go for:
initialize: function()
{
// called from Backbone constructor
// call base initialize()
joint.dia.Link.prototype.initialize.apply(this, arguments);
// link markup is so complex that we need to fetch its definition
var markup = (this.markup || this.get('markup'));
// append <title> to markup, so that it covers whole path
markup += '<title/>';
this.set('markup', markup);
}
That should give you a start at least.
I'm creating a dom structure which includes an SVG element:
<div data-bind="with: searchable_select.f0000001" style="verticalAlign: top">
<input data-bind="value: select_filter_value, valueUpdate: 'afterkeydown', event: { change: change_filter_, blur: blur_filter_ }" style="display: none">
<div>
<select data-bind="options: select_list, value: working_value, event: { change: change_selector_ }, optionsText: 'label', optionsValue: 'value'" style="display: inline-block; maxWidth: 150px">
<option value="person_full_name_asc">Member Full Name (A-Z)</option>
<option value="person_full_name_desc">Member Full Name (Z-A)</option>
</select>
<svg style="display: inline-block; verticalAlign: middle" width="18" height="18" xmlns="http://www.w3.org/2000/svg" version="1.1">
<g>
<circle cx="6" cy="6" r="5" fill="#AAAAAA" stroke="#000000" stroke-width="2"></circle>
<path fill="#AAAAAA" stroke="#000000" stroke-width="2" d="M10,10 L17,17"></path>
</g>
</svg>
</div>
</div>
The svg element does not actually display. When I find the svg element in Chrome developer tools, both width and height show as zero.
I've tried removing the style attribute. I've tried setting the width and height in the style attribute.
I've copied the svg to a separate HTML file:
<html>
<head><title>maggen</title></head>
<body>
<svg style="display: inline-block; verticalAlign: middle" width="18" height="18" xmlns="http://www.w3.org/2000/svg" version="1.1">
<g>
<circle cx="6" cy="6" r="5" fill="#AAAAAA" stroke="#000000" stroke-width="2"></circle>
<path fill="#AAAAAA" stroke="#000000" stroke-width="2" d="M10,10 L17,17"></path>
</g>
</svg>
</body>
</html>
Where it displays fine.
If I wrap the svg element in a div, the svg element shows up. In fact, if I edit the HTML in Chrome developer tools it will show up.
So, yeah, why? I've done a search on Google for this, but either it isn't there or (more likely) my Google Fu is not up to the task. I mean, sure, I can wrap it in a div - and maybe that's the right thing to do - but I'd rather not because then I'd need to wrap other stuff in divs and the dom will start to get cluttered.
EDIT: On a hunch I tried editing viewport attribute into the SVG element in Chrome tools. Voila! The element is visible! Expect when I included the viewport attribute when creating the document, it's not visible. So I tried just adding a random attribute in Chrome tools to the SVG element. Voila! The Element is visible! So, I thought, the problem is specific to Chrome and tried running it in Firefox...
...where the element doesn't show up.
EDIT: Great, so wrapping it in a div is not guaranteed to make it show up. But doing an "edit as HTML" in Chrome developer tools does make it show up.
EDIT: Well, I've gotten it to work correctly and, yes, it turns out to be a function of the Javascript creating the DOM elements. There's a lot of stuff in the code, but I can boil it down to this:
This code works (createElement creates a tag and sets attributes based on passed in parameters):
var div = this.createElement(
'div',
element_name + '_div',
null, style_options, null, null
);
div.innerHTML = [
'<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width=' + width + ' height=' + height + '>',
svg_xml.join(''),
'</svg>'
].join('');
if (parent) parent.appendChild(div);
return div;
This code doesn't:
var svg = this.createElement('svg', element_name, null, style_options, classlist, {
viewport: '0 0 ' + width + ' ' + height,
version: "1.1",
xmlns: "http://www.w3.org/2000/svg",
width: width,
height: height
});
svg.innerHTML = svg_xml.join('');
if (parent) parent.appendChild(svg);
return svg;
So, sure, I've got something working now, but I don't understand why. Or more to the point, I don't understand why one way works and the other doesn't. I have a couple of guesses, but they are just wild guesses, really.
"I've got something working now, but I don't understand why."
The issue is that the methods you were using do not create an SVG element in the SVG namespace. The xmlns attribute only affects the behaviour of an XML parser, not of DOM methods.
I'm not sure which library you're using for the this.createElement() method with multiple parameters. However, I suspect it probably starts by calling the basic document.createElement(tagName) method. This is what MDN says about the standard DOM createElement method:
In an HTML document creates the specified HTML element or HTMLUnknownElement if the element is not known. ... In other documents creates an element with a null namespaceURI.
In other words, because you're (presumably, indirectly) calling createElement on an HTML document, it always creates an HTML element. An HTML element with tag name "svg" is just treated as an unknown span-type element.
In contrast, using div.innerHTML to pass a markup string creates the SVG element correctly because it invokes the HTML5 parser to figure out what type of element to create. The namespace is determined using the same rules as when parsing markup from a file. Editing the HTML in the Chrome developer tools has the same effect.
Sidenote: Avoid calling .innerHTML on an SVG element. Some browsers support it, but it's not part of the specs. You're not getting an error because your svg variable is actually an instance of HTMLUnknownElement. Passing SVG code to the innerHTML method of a parent <div> usually works, although there are some bugs with SMIL animation. As #Robert Longson says in the comments, you can use the DOMParser object to parse either HTML or XML code into a document.
The other way to dynamically create an SVG element is to use document.createElementNS(namespaceURI, tagName). You'll also have to use this method to create all the child elements of the SVG. Once they are created, you may be able to set attributes, styles, and classes using your library methods. (But you haven't specified what library you're using, so I'm not sure.)