How do you make a div "tabbable"? - html

I have buttons that are div elements and I want to make them so that it is possible for the user to press the tab key on their keyboard and move between them. I've tried wrapping their text in anchor tags but it doesn't seem to work.
Does anyone have a solution?

Add tabindex attributes to your div elements.
Example:
<div tabindex="1">First</div>
<div tabindex="2">Second</div>
Per steveax's comment, if you don't want the tab order to deviate from where the element is in the page, set the tabindex to 0:
<div tabindex="0">First</div>
<div tabindex="0">Second</div>

for those interested, in addition to the accepted answer, you can add the following jquery to make the div style change when you tab to it, and also handle Enter and Space to trigger a click (then your click handler will do the rest)
$(document).on('focus', '.button',function(){
$(this).css('border','1px dotted black')
});
$(document).on('keyup', '.button',function(e){
if(e.which==13 || e.which==32)
$(this).click()
});
I'm sure someone has made this into a jq plugin $().makeTabStop

Add the tabindex="0"attribute to each div you want tabbable. Then use CSS pseudo classes :hover and :focus, for example to signify to the app user that the div is in focus and clickable, for example. Use JavaScript to handle the click.
var doc = document;
var providers = doc.getElementsByClassName("provider");
for (var i = 0; i < providers.length; i++) {
providers[i].onclick = function() {
console.log(this.innerHTML);
};
}
.provider {
flex: 0 1 auto;
align-self: auto;
width: 256px;
height: 48px;
margin-top: 12px;
margin-right: 12px;
text-align: center;
line-height: 48px;
text-transform: uppercase;
background-size: contain;
background-repeat: no-repeat;
background-position: 10%;
background-color: gray;
}
.provider:hover{
cursor: pointer;
}
.provider:focus{
-webkit-box-shadow: 0px 2px 8px 2px rgba(0,0,0,0.4);
-moz-box-shadow: 0px 2px 8px 2px rgba(0,0,0,0.4);
box-shadow: 0px 2px 8px 2px rgba(0,0,0,0.4);
}
<h4>Click in this area first then press tab</h4>
<div id="email" class="provider" tabindex="0">email</div>
<div id="facebook" class="provider" tabindex="0">facebook</div>
<div id="github" class="provider" tabindex="0">github</div>
<div id="google" class="provider" tabindex="0">google</div>
<div id="twitter" class="provider" tabindex="0">twitter</div>

Make elements tabbable and clickable with key press using jquery
Assumptions
All elements that are of a non-tabbable, non-clickable type and should be clickable have an onclick attribute (this could be changed to a class or other attribute)
All elements are of the same type; I will use divs.
You're using jquery
Sample html:
...
<div onclick="clicked(this)">Button 1</div>
<div onclick="clicked(this)">Button 2</div>
<div onclick="clicked(this)">Button 3</div>
...
Jquery code:
This is the code that will run when the page has loaded. It needs to run on your HTML page.
$(()=>{
// make divs with an onclick attribute tabbable/clickable
$('div[onclick]')
.attr('tabindex', '0') // Add tab indexes
.keypress((evt)=>{
var key = evt.key;
evt.preventDefault(); // Ensure all default keypress
// actions are not used
if (key === ' ' || key === 'Enter') { // Only send click events for Space
// or Enter keys
evt.currentTarget.click(); // Run the click event for element
}
});
});
You can find a working example here.

For anyone that shows up on this page for the opposite intention, as in to make a div tag NOT tabbable: https://github.com/WICG/inert is a good way.

Related

Anchor/Pseudo-URL Hide/Show-CSS Issue

I trying to experiment with single page websites. However I have come to a point where I'm stuck.
I use Anchors and :target Pseudo-classes to get a website appearing as normal website. I do this by using div's that are switched to display: block/none as needed.
My cut down code to show the issue:
function showIndex() {
document.getElementById("Index").style.display = "block";
}
function hideIndex() {
document.getElementById("Index").style.display = "none";
}
#nav, #content {
padding: 10px;
margin: 0 0 20px 0;
}
.navButton {
float: left;
width: 50px;
background-color: blue;
padding: 5px;
margin: 0 10px 0 0;
color: white;
}
.contentBox {
float: clear;
width: 400px;
border: 1px solid blue;
padding: 5px;
}
#A, #B, #C {
display: none;
}
#A:target, #B:target, #C:target {
display: block;
}
<div id="nav">
Index</div>
<div class="navButton">Page A</div>
<div class="navButton">Page B</div>
<div class="navButton">Page C</div>
</div>
<div id="content">
<div id="Index" class="contentBox">Here is the Page: Index</div>
<div id="A" class="contentBox">Here is the Page: A</div>
<div id="B" class="contentBox">Here is the Page: B</div>
<div id="C" class="contentBox">Here is the Page: C</div>
</div>
Everything workign fine and as intended as long as the side is opned through index.html. However if I open the side through its anchor / pseudo-url like index.html#A, both divs (Index + A) will be shown instead of just A.
I'm aware why both are shown. If I hide Index by default, the user will get an empty page at start. I cant use .htaccess to redirect to the very same page like Redirect index.html index.html#Index and neither is declaring index.html#Index as startpage an option for different reasons.
Does anyone know a solution to hide Index Div if the page is opened through an anchor url?
One way to do accomplish this is with the hashchange event. Of course, with this, you will also want to remove the show and hide inline event listeners.
window.addEventListener("hashchange", function (e) {
let hash = location.hash.slice(1) || "Index";
document.querySelectorAll(".contentBox").forEach((el) => {
el.style.display = el.id === hash ? "block" : "none";
});
});
Just add that inside script tags. It will run once on load, and then every time the hash changes. If the hash is empty, it will show index. Otherwise, it will try and show whatever element has the id matching whatever the hash is. Only problem with this is that if the target is to "#V" and you don't have a .contentBox with the id of V, it won't show anything. You can work around this easily enough by testing if there are any visible .contentBox after the loop, but I'll leave that for you to figure out.
Edit: I would've thought this would catch page refreshes as well, but in the case that you want to cover every single base, you could do this:
function hideHash(){
let hash = location.hash.slice(1) || "Index";
document.querySelectorAll(".contentBox").forEach((el) => {
el.style.display = el.id === hash ? "block" : "none";
});
}
window.addEventListener('load',function(){
hideHash();
window.addEventListener("hashchange",hideHash);
});
This will add the event listener for the hashChange during the load event, after firing once during the load event. Doing it this way prevents it from accidentally firing twice on page load, which would probably cause some flickering. Note - if you notice flickering on page load, you can wrap the second event listener in a setTimeout function, because hashChange fires after load, and it's theoretically possible that it will still get called during load without introducing a delay.

How do you make a Div do the same thing as a a button?

I am trying to make a navigation bar for a project and I need a button to call the function for a dropdown menu. If I have a button, I can't format it the same as a div, and it stands out from the other options. Is there a way to make a div be a button? I have tried putting the onclick attribute on it, but then the drop-down menu doesn't appear in the same spot. Thanks in advance.
(I am very new to coding, so try to explain things in simple terms)
I decided to do a hover drop-down menu which makes things a lot easier, but thank you for your answers!
There are different ways to do this. One is to use jQuery (a Javascript extension), like Branden Keck showed it to you. Another way is to use only html and Javascript: There is a html attribute which creates an Javascript event:
<div id="myDiv" onclick="clickEvent()">Some text</div>
clickEvent has to have brackets in it because it's a Javascript Function. Your Javascript could look like something like this then:
function clickEvent() {
document.getElementById("myDiv").innerHTML = "Hello World";
}
Here a snippet for that:
function myFunction() {
document.getElementById("myDiv").innerHTML = "Hello World without jQuery!";
}
$("#myDiv2").click(function() {
$("#myDiv2").html("Hello World with jQuery!");
});
$("#myDiv3").click(function() {
$("#hiddenDiv").slideToggle(750); // 750 is the sliding time in ms
});
#myDiv,
#myDiv2, #myDiv3, #hiddenDiv {
background: #0000ff;
color: #ffffff;
transition: 0.5s all;
-webkit-transition: 0.5 all;
font-family: "Arial";
width: auto;
height: auto;
font-size: 1.3em;
margin: 0.4em;
padding: 0.2em;
border-left: 1px groove #f0f0f0;
border-top: 1px groove #f0f0f0;
}
#myDiv:hover,
#myDiv2:hover, #myDiv3:hover {
background: #ffffff;
color: #000000;
padding: 0.22em;
box-shadow: 0.22em 0.22em 0.44em #000000;
}
#myDiv2, #myDiv3 {
background: #ff0000;
}
#hiddenDiv {
background: #00aa00;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<div id="myDiv" onclick="myFunction()">Click this div! Without jQuery</div>
<div id="myDiv2">Click this div! With jQuery</div>
<div id="myDiv3">Toggle hidden Text With jQuery<span style="font-size: 0.7em;font-family:Arial;font-style:italic;"> May lag because of snippet.</span></div>
<div id="hiddenDiv">You found me!</div>
You say you are very new to coding. Have you read about jquery at all? I would definitely suggest it. It is very possible to make things happen when a <div> tag is clicked with jquery functions. Here is an example:
$("#IdOfDivTag").click(function(){
alert("The paragraph was clicked.");
});
You will have to add an id or class attribute to the div tag you want an action to happen with (unless you want the same action for all <div>, in which case you can use "div" in the jquery statement).
To implement jquery you need at add a jquery library to your code... You can start here: http://www.w3schools.com/jquery/jquery_get_started.asp

Set div size of its background image

Is it possible with CSS/HTML to resize some box to match exactly it's background image size? Without using javascript.
For instance let's say I have a simplest div:
<div class="image">TEST</div>
.image {
background-image: url(http://placehold.it/350x150);
width: 350px;
height: 150px;
}
And I would like to resize it to those 350x150 dimensions without hardcoding those values. Also I cannot put any content inside this div.
http://jsfiddle.net/5Dane/
EDIT: I see a lot of answers I already was aware of, thank you for them, but that's not the solution here unfortunately. Below I'm explaining why I need such functionality.
What I'm trying to do is a form with steps (buttons previous and next). In session I hold all the values the user has input but there are some buttons which will add more functionality for the user (like multiple dynamically added rows for data). I'm doing it with jQuery of course, but I want the form to be able to work when there is no java script enabled.
Now to the point - I was trying to find out how to tell the difference which button the user has clicked. The case is all my submit buttons need to be images and the simplest solution <input type="image"/> doesn't send info about the button clicked with POST data. That's why I came to this solution:
<input class="submit_img" type="submit" style="background-image:url(http://placehold.it/108x23); width:108px; height: 23px;" value=" " name="some" />
/* Submit button with image */
input.submit_img {
font-size: 1em;
border-radius: 0px;
box-shadow: rgba(0, 0, 0, 0.15) 0 1px 1px;
border: solid 0px #000000;
cursor: pointer;
}
http://jsfiddle.net/XRvqV/
This way my form will submit all the data AND I will know which button the user clicked. Also the button looks fine, like it should look. I was wondering though if it was possible to make it a little more portable - my buttons all have different widths for different functions. Can someone suggest another approach here?
No, you can't. CSS is not aware of the the image size. You can do it easily with JQuery.
JQuery exmaple
$(function(){
var bg = $("div.image").css('background-image');
bg = bg.replace('url(','').replace(')','');
var newImg = new Image();
newImg.src = bg;
$("div.image").css("width",newImg.width);
$("div.image").css("height",newImg.height);
});
This is a hack and doesn't use background-image (uses an img tag instead), but is the only way I can think of without using JS.
HTML
<div class="container">
<div class="image">
<img src="http://www.pandafix.com/pandafix/images/untitled_1.jpg"/>
</div>
<div class="content">
some text
<br/>
some more text
<br/><br/><br/><br/>
text text text
</div>
</div>
CSS
.container {
position: relative;
}
.content {
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
color: red;
}
Basically, you allow an img tag to determine the height and width of a container. Then, overlay whatever content you want on top of the image (I'm assuming you want to put something on top).
jsFiddle
i would suggest you a alternative way to solve your problem. if you use bootstrap you can involve a div to make resizable image.
<div class="img-responsive">
<img src="test.jpg" width='xxx' height='yyy' alt='test'>
</div>
You can't do that using just HTML. But you can do this using HTML!
You should try this:
background-size: values;
This way, you will resize the background-image to the size of the container!
You can't do it directly.
The only solution it would be fetching the BG of the DIV element and attach new DOM img element to the DOM node, afterwards you could use the info of the image to add the proper with and height..
if you are willing to use jquery you can do this.
$(function(){
$('.image').each(function(index,element){
var _t = $(this);
_t.data("LinkedImg","LinkedImage"+index);
$('body').append(
$('<img />',{
id:"LinkedImage"+index,
src:_t.css('background-image')
}).hide());
});
$('document').on('load',function(){
$('.image').each(function(index,element){
var _t = $(this);
var _tmp_img = $('#'+ _t.data("LinkedImg"));
_t.css({
width:_tmp_img.width(),
height: _tmp_img.height()
});
});
});
})

Dynamic Div or assigning multiple functions to a Div in CSS/HTML

I'm relatively new to Web dev. The question is generic, but I'll pose specific user-cases.
Use-case 1:
I have a div element on a web page. When the page loads the first time, this div runs a small 5 sec animation. What I wish to do is, when this animation ends, I want the same div to contain some other element - it could be an image, a link, another animation etc.
That is, one container - the div - hosting multiple elements on a time-scale. First 5 secs animation , followed by an image or a link.
What Javascript methods will allow me to do so?
Use-case 2:
Again, I have a div element in a page. Now this div element is like a tabbed browser - you click on a different tab to view a different web page. Similarly, I wish to make this a "tabbed" div. As in, when the user hovers the mouse on tab 1, the div would show a video, when hovered over tab 2, it would show another video in the same div - that is, replacing the old video. The tabs can be considered as a fancy looking link.
Or, in the first place, is there an alternative to 'div' to do the things mentioned above?
Thanks,
SMK.
Solution for use case 2 -
This is a slightly lengthy solution but its extremely flexible and can be scaled up to any number of tabs very easily
We will divide the solution into 3 parts - The CSS, HTML and JQuery.
Lets take a look at the CSS part first
<style>
#tab_holder {
width: 350px; !important
}
#tab_holder .tabs {
float: left;
height: 20px;
padding: 5px;
border: 1px solid #eee;
border-bottom: none;
width: 50px;
cursor: pointer;
border-radius: 5px 5px 0 0;
}
#tab_holder .tabs:hover {
background-color: #eee;
}
#tab_holder #content_holder {
width: 400px; !important
margin: 0 0 0 0;
border: 1px solid #000;
padding: 10px;
float: left;
border-radius: 0 5px 5px 5px;
}
.content {
visibility: hidden;
}
</style>
Let us now take a look at the HTML part of this solution
<div id="tab_holder">
<div id="tab1" class="tabs">Video1</div>
<div id="tab2" class="tabs">Video2</div>
<div id="tab3" class="tabs">Video3</div>
<div id="content_holder">
<div id="main_content">Select a tab to see the video..</div>
</div>
</div>
<!-- These are divs in which you put your actual content.
They are always hidden -->
<div id="content1" class="content">
<iframe width="200" height="200" src="http://www.youtube.com/embed/4Z6YUGGlwtA?rel=0" frameborder="0" allowfullscreen></iframe>
< /div>
<div id="content2" class="content">
<iframe width="200" height="200" src="http://www.youtube.com/embed/s13dLaTIHSg?rel=0" frameborder="0" allowfullscreen></iframe>
</div>
<div id="content3" class="content">
<iframe width="200" height="200" src="http://www.youtube.com/embed/I1qHVVbYG8Y?rel=0" frameborder="0" allowfullscreen></iframe>
</div>
You can see that each tab is represented by a div which is using the "tabs" class from the CSS section. If you need to add a new tab, all you have to do is add a new div and give is a new id. For example to add a forth tab, you can say -
<div id="tab4" class="tabs">Video4</div>
It is as simple as that.
Now the thing I like about this approach is that you can place the content to be displayed also in div's, rather that nesting it under jquery. In this case we use the div's with the id content1 content2 content3
This gives you the flexibility to expand as you enter content into the div and use normal markup without getting confused and at ease.
These div's are not visible as we have set their visibility to hidden is CSS.
If you add a new tab div you must also add a new content div.
Now we move onto the JQuery part -
$(document).ready(function (){
/* Add the listeners. */
$("#tab1").mouseover(function (){
switch_content('content1')
});
$("#tab2").mouseover(function (){
switch_content('content2')
});
$("#tab3").mouseover(function (){
switch_content('content3')
});
});
function switch_content(name){
$("#main_content").fadeOut('fast',function (){
$("#main_content").html($("#"+name).html());
$("#main_content").fadeIn('fast');
});
}
The above JQuery function is extremely straight forward. Each tab is attached a action listener which is fired by a mousover event. So if you add another tab with the id=tab4 and its respective content div with the id=content4 then all you have to add in the jQuery is:
$("#tab4").mouseover(function (){
switch_content('content4')
});
So it becomes very easy to expand the code.
You can find a working demo of this on my website demo section
Tips -
Avoid using hover because it creates an annoying user experience due to accidental hovers and it is hard for mobile platforms to emulate this event. Most of them fall back to click. So I suggest use the click event instead.
If you must use, make use of the HTML video tag and pause the video using JS if the user hovers on another tab. This will render a better user experience.
Here is an example for use-case 1.
In your html you need to include the 5 second animation, i persume this is a gif? Although it can be any content. For the sake of this example i will show it as a div.
The html i have used:
<div id="example">
<div id="somecontent"> </div>
<div id="morecontent"> </div>
</div>
The CSS:
#example
{
width:500px;
height:500px;
background-color:#f00;
padding:10px;
}
#somecontent
{
width:200px;
height:200px;
background-color:#fff;
}
#morecontent
{
width:200px;
display:none;
height:200px;
background-color:#000;
}
and the javascript(using jQuery):
setTimeout(function() {
$("#somecontent").fadeOut("slow", function() {
$("#morecontent").fadeIn("slow");
});
}, 5000);​
Have a look at this jsfiddle for it in action - http://jsfiddle.net/fntWZ/
For use case 2 it will be more complicated. Try having a look for some different plugins that could help with this
answer for use-case:1
css :
<style>
#myDiv {
height:0;
width:0;
position:absolute;
border:1px solid red;
}
</style>
script :
$(document).ready(function(){
$("#myDiv").animate({width:"100px", height:"100px"},5000, function(){
var image = new Image();
image.src = "dropdownContainerBottomMiddle.png"; //your image src goes here
$("#myDiv").append(image);
//you can append more content by using setTimeout function
setTimeout(function(){
var anc = "stackoverflow";
$("#myDiv").append(anc);
}, 1000);
});
});
html:
<div id="myDiv"></div>

Make visible/unvisible div on click on other div

Can anybody help me, I need something like http://web-kreation.com/demos/login_form_mootools_1.2/, just mush simpler, when I click on one div ( login in this case) just to show other and if I click again to make unvisible. How to do that with Mootools if I have two divs ( div id=login and div id=vis_unvis) ?
Please refer to the following thread to learn more how toggle element’s visibility via the javascript:
Toggle Visibility - Show/Hide Anything
to replicate the effect in the example to it's most basic, look at this fiddle:
http://jsfiddle.net/dimitar/9Syj3/
(function() {
var loginOpen = false, loginForm = document.id("login").set("morph", {
link: "chain"
}).setOpacity(0);
document.id("toggler").addEvents({
click: function() {
loginForm.morph((loginOpen) ? {
marginTop: -90,
opacity: 0
} : {
marginTop: 0,
opacity: 1
});
loginOpen = !loginOpen;
this.set("text", loginOpen ? "Hide form" : "Show form");
}
});
})();
with html of:
<div id="login">
This be the login form
</div>
<div id="toggler">Show form</div>
and css of:
#login {
width: 300px;
background: #ccc;
height: 50px;
padding: 10px;
position: absolute;
margin-top: -90px;
margin-left: 300px;
z-index: 1000;
-moz-box-shadow: 0 0px 3px 3px #000;
}
resources for mootools: Fx.Morph or the element prototype .morph() allows you to animate properties of an element, in this case modifying marginTop and opacity.
mootools also supports Fx.Slide, Fx.Reveal and more as part of the mootools-more official collection of plugins.
of course to hide/show, you could just toggleClass a css class which has display: none on the element or use .show() / .hide() or .fade("in") / .fade("out") to hide via opacity.
NO end to ways to handle this. Check Fx.Move too :)