using images as buttons in html5 - html

I am making a web app that plays sounds. The interface I would like to use is that of a piano/keyboard. User will press a key and sound is played.
I have used <button> to call the functions and embedded images of keys inside them but it does not look good and has a border around each key.
<button onclick="freqA4()">
<img src="keyboardpics/key1.jpg" />
</button>
Is there a GUI designer for HTML5 that will allow me to use attratcive high res images and assign events to them?
Or should I use canvas to animate a keyboard and assign function calls to certain areas like image mapping?
A large emphasis of this app will be on the appearance.
Any help would be great as I have very little experience in html/html5.

First include this in your HTML: http://meyerweb.com/eric/tools/css/reset/
Define each button as CSS style
.button {
width: <button width>
height: <button height>
}
#key1 {
background: url('/keyboardpics/key1.jpg') no-repeat
}
#key2 {
background: url('/keyboardpics/key2.jpg') no-repeat
}
In your HTML
<div id="key1" class="button"></div>
<div id="key2" class="button"></div>
...

You can use normal links links (<a> tags), or you can use input elements of type image <input type="image" src="keyboardpics/key1.jpg" onclick=freqA4()" />.
You can of course use CSS to style any of them (even the button you use)

Related

HTML Validation: Why is it not valid to put an interactive element inside an interactive element?

Disclaimer: I understand that it is not valid HTML. I am trying to understand why is it not allowed?
W3C suggests that an interactive element like button or a mustn't contain another interactive element.
I could find a lot of resources mentioning this rule and some workarounds, also some resources related to how this impacts accessibility and screenreaders, but almost all of those resources talk about the fact that this is a requirement but do not explain why.
https://adrianroselli.com/2016/12/be-wary-of-nesting-roles.html
https://codepen.io/vloux/pen/wXGyOv
Nesting <a> inside <button> doesn't work in Firefox
https://github.com/dequelabs/axe-core/issues/601
I wasn't really able to find an explanation for why is it not allowed? does it lead to any usability problems?
This is a related question:
Why should interactive element not be used within an anchor?
The accepted answer is satisfactory but is not enough to make this rule a requirement. The described situation can be avoided using proper event handling.
Also, if nested interactive content is invalid, how are we supposed to have something like this:
A card which is clickable as a whole, and also has a clickable secondary CTA inside it.
I know a workaround would be to have a primary and secondary CTA inside the card, but shouldn't the above be allowed as well?
Here is a fiddle:
https://jsfiddle.net/t9qbwas5/2/
<button type="button" class="card">
The card itself is the primary CTA.
<br/>
<br/>
some important content to read through.
some important content to read through.
some important content to read through.
<div class="cta">
Secondary CTA
</div>
</button>
.cta {
padding: 4px;
background: #00a9a9;
color: white;
width: 80px;
margin: auto;
margin-top: 8px;
margin-bottom: 8px;
}
.card {
width: 200px;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
In the above example, I am achieving this by using a clickable div inside the button, but that is not semantic (?) and also functionality wise, it is an interactive element inside another one. I am trying to understand that even if I use this workaround, is it fundamentally wrong to have nested interactive elements? is it a bad design/usability practice?
The answer is actually quite simple in principle. When you click on the interactive element inside another interactive element which function should you trigger?
In your example if I click on Secondary CTA should it fire the function for secondary CTA or should it fire the function for the card?
The fiddle below should demonstrate the problem, tab into the first button and press enter, then tab into the CTA and press Enter.
Obviously you could work around this but I think it demonstates the point.
$('.card').on('click', function(){
console.log("card");
});
$('.cta').on('click', function(){
console.log("cta");
});
.cta {
padding: 4px;
background: #00a9a9;
color: white;
width: 80px;
margin: auto;
margin-top: 8px;
margin-bottom: 8px;
}
.card {
width: 200px;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" class="card">
The card itself is the primary CTA.
<br/>
<br/>
some important content to read through.
some important content to read through.
some important content to read through.
<div class="cta" tabindex="0">
Secondary CTA
</div>
</button>
This principle then continues through to Screen Readers and other Augmentative and alternative communication (AAC) devices.
Should they take into account the parent element when describing the child element? Should they allow the use of Space to activate if you nest a checkbox within a <button>, should Enter then affect only the button or both?
A card which is clickable as a whole, and also has a clickable secondary CTA inside it.
Although visually imaginable and technically possible, it's not accessible for assistive technologies, like screenreaders
Let's make a simple example:
<button>
Click for action 1
<button>Click for action 2</button>
</button>
The accessible name for the first <button> would be "Click for action1 Click for action 2". And if you define an aria-label="Click for action 1", then the inner button element would not be read at all.
If you really want to make a whole element clickable, you can perfectly use javascript and still be accessible
<div class="outer">
<button type="button" class="card">
The card itself is the primary CTA.
</button>
<br/>
<br/>
some important content to read through.
some important content to read through.
some important content to read through.
<button class="cta">
Secondary CTA
</button>
</div>
<script>
$(".outer").on("click", function() {$(".card").click()});
</script>
<style>
.outer {cursor: pointer}
</style>
With this example, you will correctly have two buttons rendered to screenreaders, the first one "The card itselfis the primary CTA" and the second one "Secondary CTA", while a mouse click on the whole card would lead the same action as the first button.
It's hard to answer "why" questions, because there are many factors to be considered and ultimately the reason is that the specification specifies it, but I'll give it a try.
When this behavior was spec'ed, this design style was not very common. A link was normally either a single image or a small portion of text. Take a look at this link to an article from the year 2000:
]
Only the title and the image are interactive. The rest is simple text.
Even today, this is not so common. Take also look at the Microsoft 365 pricing page:
Note how the card itself is not interactive, only the things inside it. You can see the primary CTA "Buy now" in the form of a button and the secondary CTAs in the form of hyperlinks.
Now, about your example: Is that card really a button? It might be subjective, but for me that's not a button. A button normally appears with a color scheme contrasting with the surrounding page. I would make the card a <div> and the secondary CTA a <button>.
However it might be confusing to users, as the card doesn't seem much interactive to me. Consider adding cursor: pointer to the <div> (beyond all the things necessary for accessibility)`.
I noted you tagged accessibility. I think this is not a great idea for people using screen readers, and I think most screen readers would have problems interpreting a button inside a button (if the browser accepted that at all).
I would use the "Microsoft 365 pricing page approach" instead. It's simpler and works well with HTML.
One important problem is related to event-capturing; if you click on a interactive element nested inside another interactive element(e.g. a select inside a clickable button) there would be an interference here and two case might happen depends on the browser;
case 1 is that both element will raise that event (e.g. click) event
 
case 2 is that parent element will capture the event and the nested element won't raise that event
in fact both cases will result in non-deterministic behavior;
This is not limited to click events actually, but click event is more tangible; Also the screen reader will fail to parse the markup; keyboard-interaction won't work as expected; try it in the snippet below:
del.addEventListener('click', function(){
console.log('deleting ...')
})
save.addEventListener('click', function(){
console.log('saving ...')
})
sel.addEventListener('change', function(){
console.log('changing to', sel.value)
})
<div id='del'>
delete
<button id='save'> save
<select id='sel'>
<option>foo</option>
<option>bar</option>
<select>
<input name='a' type='radio' />
<input name='a' type='radio' />
<input name='a' type='radio' />
</button>
</div>

Anchor or button [duplicate]

This question already has an answer here:
Why are buttons discouraged from navigation?
(1 answer)
Closed last year.
What element should I use for JavaScript actions?
Actions that does something like play/pause/stop/new/open/save/print/close, etc.
<a id="play" href="#">Play</a>
Play
<button id="play" tabindex="0">Play</button>
<div id="play" role="button" tabindex="0">Play</div>
I see many people use anchors <a> with a href="#" but that doesn't feel very semantic, it feels like anchors are for hyperlinks that point to a resource, not for actions that does stuff. Then you have to hack it around with event.preventDefault (i.e. return false).
I rarely see people use the <button> element, but isn't it what is supposed to be used?
TLDR; you can open an anchor link in a new Tab/Window but not a button.
Here is a rule of thumb:
For navigation just use anchor it's alright to style it as a
button and let it use it's href attribute well.
For quick actions (play,pause,stop,+1 like) just use button it
doesn't have href for a reason!
Consider this code.
const [anchor] = document.getElementsByTagName('a')
const [button] = document.getElementsByTagName('button')
anchor.addEventListener('click', e => {
console.log('anchor clicked')
e.preventDefault()
}, false)
button.addEventListener('click', e => {
console.log('button clicked')
})
a {
text-decoration: none;
padding: 2px;
}
button {
background: none;
border: none;
font-size: 16px;
}
.btn {
background-color: blue;
color: white;
display: inline-block;
text-align: center;
}
<a class="btn" href="#">
Anchor
</a>
<hr/>
<button class="btn" type="button">
Button
</button>
Styling
They both look almost alike (with minimal justifications) the only problem is that you'll have to undo some stylings that come with button like border & background but with anchor you don't get the clicking popping animation that you'd get with button.
Functionality
But since the anchors <a> need <a href="some/path"> to work even if it's just #, unless you need to navigate after clicking the anchor you'll have to use e.preventDefault() in your javascript to prevent it.
The best way to decide which element has the best semantics for a JS based user interaction is to ask what you want to happen if the JS fails (which it will.
Think progressive enhancement. Think unobtrusive JavaScript.
Should the user just go to another page? Use a link. The href will be the fallback from when the JS fails.
Should the user go to another page while sending some data or making a POST request? Use a button, put it in a form.
Is it impossible to have any kind of server fallback? Use a <button type="button"> and consider generating it from JS/DOM instead of HTML.
Then you have to hack it around with event.preventDefault
You could set the href to javascript:void(0) rather than #, which would prevent execution without having to use event.preventDefault()
But buttons are probably better for this sort of thing
This is more of a preference thing.
Personally, I prefer to either use the <button> tag or make my own.
If it makes more sense to you to use the <button> tag, use it. If it works, it's not wrong. =)

HTML Help Button with image: what's the best semantic for this?

I want to create an HTML help button (that looks like an image).
What is the best semantic way to do it ?
Here's what I was thinking about:
1st solution:
HTML
<button class='help'>
<img/>
</button>
2nd solution:
HTML
<button class='help'>
</button>
CSS
button.help
{
background-image:...;
}
3rd solution
HTML
<img class='button' src='blabla'/>
I think the button tag is indispensable as it will behave like a button (you can click on it to get some help, basically)
If you are using the button for some form submission, than I would prefer using
<input type="image" src="PATH_TO_IMAGE" alt="Submit Button" />
If you want to stick to the button tag, I would prefer using the background-image way.
Why?
Well, you can use CSS Sprites for your website and place the image on the canvas, than map the images using background-position property, this way it will reduce http request by one, in fact not just one, it will save you more if you wish to have more buttons with different images later...
I would say:
<button class='help'>
</button>
Could also add:
<button class="help" role="button">Help</button>

How do I center HTML objects on an MVC 4.0 Web API using Razor application?

Okay, bear with me because I'm new to WEB development.
I have an MVC 4.0 Web API application using Razor and Entity Framework 5 (C#).
One of my links takes me to a page which displays data from the EF.
I added an HTML button to this page called "Export to Excel."
I want to center this button on the screen, above the report results.
What is the correct approach for this and how do I do it? I need to understand the PROPER architecture for files and code.
Do I use CSS? If so, where do I store the file in the solution? How do I use it on my page?
Do I do something specific to Razor?
Should I simply use HTML tags like
Again, all I want to do is center a button on the web page.
Can someone help me with a step by step process to do this correctly?
I'm just having a hard time figuring out where to put code and files (basically how to structure the application properly).
You can use CSS.
.centerAlign {
text-align: center;
}
In your view you can then apply the centerAlign class to the button:
<button class='centerAlign' />
You can also make a custom HTML Helper that will automatically apply the class for you.
namespace YourApplication.Helpers
{
public static class ButtonExtensions
{
public static string ButtonCenter(this HtmlHelper helper, string value)
{
return String.Format("<button class='centerAlign'> {0} </button>", value);
}
}
}
Then in your view you could do:
#Html.ButtonCenter("Click me");
I know there is an answer, but this is a really common way to center objects margin: 0 auto. Since the answer by itself doesn't really explain, I'll provide some detail.
When you build your View it is marked as a .cshtml file. Your View will contain a series of HTML or Hyper Text Markup Language. What you are doing is utilizing a particular Element called a div. These are used to help build a structure or layout for your site.
<div id="Origin">
<div class="origin-container">
<div class="header-style">
<div id="Origin-Header">
<div class="header-container">
// Inside Header Elements
</div>
</div>
</div>
</div>
</div>
So essentially this is a Site Structure. You'll notice that I have a tendency to inner-wrap a lot of my Elements. That is because it makes it easier to customize and style my layout, making it more customizable.
If your thinking "How is it more customizable?" Your partially correct, this HTML is simply a structure- The customization will come from your Stylesheet, Cascading Stylesheet to be exact.
Your HTML will call this Stylesheet to help adapt your layout to give a consistent appearance. So if you'd like to center your header you would put in your stylesheet:
#Origin-Header {
margin: 0 auto;
}
What the command is stating is three things:
Margin: These are the page margins.
0: Is the pixel difference for Top and Bottom.
Auto: The left and right pixels.
So rather then a top, bottom, left, and right they are all merged together in the short-hand. You'll have a lot of additional control to your layout as well through your stylesheet. Bare in mind that this is manipulating those div tags. If your trying to align a particular object, it would work identical but rather then focus on the element- You would point it to your html object.
But I hope that helps.
I do not know if it is good practice, but the only way I have been able to center entire controls like a button in HTML was to do something like
.btn{
margin-left:auto;
margin-right:auto;
}
I have been able to center the control by setting the button's class to "btn" and using the above css. The text-align property has never really worked for me in HTML.
Try this:
[i guess is this what you are looking for]
check LIVE DEMO on jsfiddle
HTML
<section class="iHaveBorder">
<h3>Help me here!...Center stuff...</h3>
<div class="myWorderfullDiv iAmRed">
your report here...
</div>
<center>
<button>DoIt</button>
</center>
</section>
<h1>::::::OR:::::</h1>
<section class="iHaveBorder">
<h3>Help me here!...Center stuff...</h3>
<div class="myWorderfullDiv iAmBlue">your report here...</div>
<div style="text-align: center;" >
<button>DoIt</button>
</div>
</section>
<h1>::::::OR relative:::::</h1>
<section class="iHaveBorder iFeetIn">
<h3>Help me here!...Center stuff...</h3>
<div class="myWorderfullDiv iAmGreen">your report here...</div>
<div class="iWant2BeCenter">
<button>DoIt</button>
</div>
</section>
CSS:
.myWorderfullDiv{
height: 80px; width: 200px;
}
.iAmBlue{background-color: blue}
.iAmRed{background-color: red}
.iAmGreen{background-color: green}
.iHaveBorder{border:2px black solid;}
.iFeetIn{display: inline-block;}
.iWant2BeCenter{text-align: center;}
check LIVE DEMO on jsfiddle

How to change the behavior and style of an html file field?

I'd like to create a file upload field that displays an input type=text (displaying the filename), with the upload button replaced with a custom image.
Something like this:
A simple solution without any hacks would be appreciated.
You won't find any solutions that aren't hacks due to how browsers handle the file upload field. Due to security concerns they restrict the amount of styling you can do to them to prevent a malicious website from making them look like something they are not. How limited you are varies from browser to browser but without using JavaScript and hacky tricks you will not be able to style a file upload field to your liking through straight HTML/CSS.
<INPUT type="image" class="myButton" value="">
.myButton {
background:url(YOUR IMAGE) no-repeat;
cursor:pointer;
width: 200px;
height: 100px;
border: none;
}
using buttons
<button type="submit" style="border: 0; background: transparent">
<img src="/images/Btn.PNG" width="90" heght="50" alt="submit" />
</button>
If you are using jQuery, have a look at this plugin - https://github.com/ajaxray/bootstrap-file-field
This tiny plugin will display the file input field as a bootstrap button (with configurable classes), similar in all browser and will show selected file names (or selection errors) beautifully.
Additionally you can set various restrictions using simple data-attributes or JS settings. e,g, data-file-types="image/jpeg,image/png" will restrict selecting file types except jpg and png images.