Shields: Provide the endpoint response's label and message as an alt text option

Created on 28 Jul 2019  路  6Comments  路  Source: badges/shields

Issue
Currently, when using the JSON endpoint method of generating a badge, the returned img element has an alt="". A user should be able to use the endpoint's label and message to populate the alt attribute. This is a use case where presumably the badge information is being generated dynamically, and therefore a user can't reliably fill in the alt text themselves.

This creates an accessibility issue where screen reader users are not able to receive the same information. The information that is visually apparent is not programmatically present.

Expected Behavior
For example, if I'm grabbing some code coverage information from a third party, and return the following object:
{ "schemaVersion": 1, "label": "Line Coverage:", "message": "98%", "color": "orange" }

Then then generated badge img should be:

<img alt="Line Coverage: 98%" src="<the-generated-url>">

I'd suggest that the default behavior be that the label and message be the alt attribute, though providing the option to override that would also be appreciated.

Thank you!

question

All 6 comments

Hi! Thanks for your question.

What do you mean, the returned img element? Are you talking about the "Copy HTML" option under the "Customize and test" section of the frontend?

Added: That's generating e.g.

<img alt="Custom badge" src="https://img.shields.io/endpoint?url=https%3A%2F%2Fshields.redsparr0w.com%2F2473%2Fmonday">

with an alt of "Custom badge", so I guess I have no idea what you mean!

Hi Paul,

Thanks for your time!

I'm referring to the img element in the below picture from the example JSON page. Where the "is it monday" img has an alt of null (alt=""). But I would expect the alt to contain the text in the image "is it monday no". And to be able to provide the label and message properties to the alt of any badge.

Let me know if that makes sense.

Thanks!

Capture

Hmm, I'm not totally sure what you want to accomplish.

When you embed the badge in a web page using an element, if the badge is dynamic, that means you don't know what the text will be until the endpoint is hit. If the badge is always the same, sure, you can put the text in the alt attribute, though you may as well use a static badge instead of the endpoint badge.

The web page you're looking at is solely for previewing so the only thing that would make sense to use for an alt is something like "endpoint badge preview".

And again, there's the same issue which is that the alt attribute needs to be set on the frontend, and the contents of the badge is not known by the frontend.

Not quite sure what you're wanting to accomplish, though if accessibility is the goal maybe we could emit something useful in the of the svg</a>?</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars2.githubusercontent.com/u/1487036?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="paulmelnikow picture"> <strong>paulmelnikow</strong> <span class="text-muted ml-1">on 20 Aug 2019</span> </div> <div class="col text-right"> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>Hmm perhaps I'm not understanding the underlying technology here.</p> <p>I would imagine if you're hitting an endpoint with the expected message and label values, you're using that to generate the img, and you could also return those values as the img alt.</p> <p>I'm not flagging this issue as solely for this endpoint badge preview page, but for anyone using the service. For example, on my <a rel="nofollow noopener" target="_blank" href="https://github.com/nodes777/flower-game-phaser3">github page</a> the line coverage badge is being generated dynamically. But I'm manually filling in the alt text with "lines coverage", and as you say I can't provide the percentage covered.</p> <p>I think I'm misunderstanding the technology here, I suppose in markdown the only alt that can be provided is the manual one. I think this can be closed until I have a clearer grasp on how the whole system works.</p> <p>Thanks for investigating!</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars0.githubusercontent.com/u/10222435?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="nodes777 picture"> <strong>nodes777</strong> <span class="text-muted ml-1">on 20 Aug 2019</span> </div> <div class="col text-right"> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <blockquote> <p>I'm not flagging this issue as solely for this endpoint badge preview page, but for anyone using the service. For example, on my <a rel="nofollow noopener" target="_blank" href="https://github.com/nodes777/flower-game-phaser3">github page</a> the line coverage badge is being generated dynamically. But I'm manually filling in the alt text with "lines coverage", and as you say I can't provide the percentage covered.</p> <p>I think I'm misunderstanding the technology here, I suppose in markdown the only alt that can be provided is the manual one.</p> </blockquote> <p>Yea, in general this is not possible using <code><img alt></code>, as the <code><img></code> is part of the source code of the calling web page and all we do is generate the source that the <code><img></code> points to. The alt text necessarily has to be set by the calling web page.</p> <p>The only things I think we could possibly do here would be to set <code><title></code>, and we could add functionality to our UI to add a field that lets you type in a value that's used for the generated HTML. Feel free to experiment and if you think either of those makes sense, let us know. Thanks!</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars2.githubusercontent.com/u/1487036?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="paulmelnikow picture"> <strong>paulmelnikow</strong> <span class="text-muted ml-1">on 20 Aug 2019</span> </div> <div class="col text-right"> 👍<span class="ml-2 mr-3">1</span> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>While it is unrealistic to include actual badge text in an alt tag for the reasons Paul has explained, there is a reasonable point raised in this issue: On the shields.io website, there are several places where we've got <code><img></code> tags without any alt tag at all, and we can easily fix this. I've submitted PR #3903 to at least improve that</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars1.githubusercontent.com/u/6025893?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="chris48s picture"> <strong>chris48s</strong> <span class="text-muted ml-1">on 22 Aug 2019</span> </div> <div class="col text-right"> 👍<span class="ml-2 mr-3">1</span> </div> </div> </div> </div> </div> <div class="col-12"> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown text-center helpful"> <div class="title">Was this page helpful?</div> <div class="mt-1" onMouseLeave="rating(473772522, 0);"> <i class="fas fa-star inactive" id="star-1" onMouseOver="rating(473772522, 1);" onclick="rate(473772522, 1);"></i> <i class="fas fa-star inactive" id="star-2" onMouseOver="rating(473772522, 2);" onclick="rate(473772522, 2);"></i> <i class="fas fa-star inactive" id="star-3" onMouseOver="rating(473772522, 3);" onclick="rate(473772522, 3);"></i> <i class="fas fa-star inactive" id="star-4" onMouseOver="rating(473772522, 4);" onclick="rate(473772522, 4);"></i> <i class="fas fa-star inactive" id="star-5" onMouseOver="rating(473772522, 5);" onclick="rate(473772522, 5);"></i> </div> <div class="description text-small"><span id="rating-val">0</span> / 5 - <span id="rating-count">0</span> ratings</div> </div> </div> <div class="mb-4"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-3835332123789605" data-ad-slot="3452512275" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div> </div> </div> <div class="col-12 col-lg-4"> <div id="ph-above-related"></div> <div class="card card-custom issue-box"> <div class="card-body pt-3 pb-5"> <h2 class="mb-4">Related issues</h2> <div> <strong> <a href="/shields/106009623/github-badges-are-unresponsive-rate-limiting">GitHub badges are "unresponsive": rate limiting</a> </strong> </div> <div class="text-muted text-small mt-2"> <img src="https://avatars2.githubusercontent.com/u/375027?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="ducin picture"> <strong class="pr-1" dir="ltr">ducin</strong>  路  <span class="px-1" dir="ltr">51</span><span>Comments</span> </div> <hr /> <div> <strong> <a href="/shields/25038840/branding-logotype">Branding / Logotype</a> </strong> </div> <div class="text-muted text-small mt-2"> <img src="https://avatars0.githubusercontent.com/u/1258?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="bryanveloso picture"> <strong class="pr-1" dir="ltr">bryanveloso</strong>  路  <span class="px-1" dir="ltr">37</span><span>Comments</span> </div> <hr /> <div> <strong> <a href="/shields/204598320/servers-fail-to-respond-to-certain-requests-fast-enough-at">Servers fail to respond to certain requests fast enough at peak time</a> </strong> </div> <div class="text-muted text-small mt-2"> <img src="https://avatars1.githubusercontent.com/u/26580?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="tony19 picture"> <strong class="pr-1" dir="ltr">tony19</strong>  路  <span class="px-1" dir="ltr">31</span><span>Comments</span> </div> <hr /> <div> <strong> <a href="/shields/481137817/intermittent-502-responses-from-camo-githubusercontent-com">Intermittent 502 responses from camo.githubusercontent.com</a> </strong> </div> <div class="text-muted text-small mt-2"> <img src="https://avatars2.githubusercontent.com/u/8525409?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="adamjstone picture"> <strong class="pr-1" dir="ltr">adamjstone</strong>  路  <span class="px-1" dir="ltr">36</span><span>Comments</span> </div> <hr /> <div> <strong> <a href="/shields/406109835/hsts-preload-list-status-http-security">HSTS preload list status (HTTP security)</a> </strong> </div> <div class="text-muted text-small mt-2"> <img src="https://avatars3.githubusercontent.com/u/4225430?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="yvele picture"> <strong class="pr-1" dir="ltr">yvele</strong>  路  <span class="px-1" dir="ltr">33</span><span>Comments</span> </div> </div> </div> <div class="sticky-top pt-4"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-3835332123789605" data-ad-slot="3919948963" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> <div id="ph-below-related-2" class="mt-4"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-3835332123789605" data-ad-slot="3919948963" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div> </div> <div class="col-12 col-lg-4"> </div> </div> <div class="skyscraper-container"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-3835332123789605" data-ad-slot="7879185320" data-ad-format="vertical" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div> <div class="mt-5 spacer"></div> <footer class="mt-5 pb-2 py-4 text-center mt-auto"> <div class="container"> <a class="navbar-brand logo mr-5" href="/"> <img src="/assets/img/logo.svg" width="40" height="40" alt="bleepingcoder logo"> bleeping<strong>coder</strong> </a> <div class="mt-4"> bleepingcoder.com uses publicly licensed GitHub information to provide developers around the world with solutions to their problems. We are not affiliated with GitHub, Inc. or with any developers who use GitHub for their projects. We do not host any of the videos or images on our servers. All rights belong to their respective owners. </div> <div> Source for this page: <a href="https://www.github.com/badges/shields/issues/3795" rel="nofollow noreferrer" target="_blank">Source</a> </div> </div> <hr class="mb-5 mt-5"> <div class="container"> <div class="row"> <div class="col-sm-4 col-lg mb-sm-0 mb-5"> <strong>Popular programming languages</strong> <ul class="list-unstyled mb-0 mt-2"> <li class="mb-2"> <a href="/python" dir="ltr">Python</a> </li> <li class="mb-2"> <a href="/javascript" dir="ltr">JavaScript</a> </li> <li class="mb-2"> <a href="/typescript" dir="ltr">TypeScript</a> </li> <li class="mb-2"> <a href="/cpp" dir="ltr">C++</a> </li> <li class="mb-2"> <a href="/csharp" dir="ltr">C#</a> </li> </ul> </div> <div class="col-sm-4 col-lg mb-sm-0 mb-5"> <strong>Popular GitHub projects</strong> <ul class="list-unstyled mb-0 mt-2"> <li class="mb-2"> <a href="/microsoft/vscode" dir="ltr">vscode</a> </li> <li class="mb-2"> <a href="/numpy/numpy" dir="ltr">numpy</a> </li> <li class="mb-2"> <a href="/ant-design/ant-design" dir="ltr">ant-design</a> </li> <li class="mb-2"> <a href="/mui-org/material-ui" dir="ltr">material-ui</a> </li> <li class="mb-2"> <a href="/vercel/next-js" dir="ltr">next.js</a> </li> </ul> </div> <div class="col-sm-4 col-lg mb-0"> <strong>More GitHub projects</strong> <ul class="list-unstyled mb-0 mt-2"> <li class="mb-2"> <a href="/rust-lang/rust" dir="ltr">rust</a> </li> <li class="mb-2"> <a href="/moment/moment" dir="ltr">moment</a> </li> <li class="mb-2"> <a href="/yarnpkg/yarn" dir="ltr">yarn</a> </li> <li class="mb-2"> <a href="/mozilla/pdf-js" dir="ltr">pdf.js</a> </li> <li class="mb-2"> <a href="/JuliaLang/julia" dir="ltr">julia</a> </li> </ul> </div> </div> </div> <hr class="mb-5 mt-5"> <div class="container text-muted"> 漏 2026 bleepingcoder.com - <a href="/bleeps" rel="nofollow">Contact</a><br /> By using our site, you acknowledge that you have read and understand our <a href="/cookies" rel="nofollow">Cookie Policy</a> and <a href="/privacy" rel="nofollow">Privacy Policy</a>. </div> </footer> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha256-4+XzXVhsDmqanXGHaHvgh1gMQKX40OUvDEBTu8JcmNs=" crossorigin="anonymous"></script> <script async src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script> <!--<script defer type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5fb2db66acbd74b2"></script>--> <script type="text/javascript" src="/assets/js/main.js"></script> <script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script></body> </html>