Context: I'm using bootstrap 4.1 in a vue.js app.
I have a table that shows the results of a user performed search.
The users are able to "see mode details" by clicking on any row of this results table. So far so good with the mouse.
How do I make the same table accessible with the keyboard?
Expected outcome:
users perform a search
the data is shown in the table
by pressing TAB they focus the <table>
(the "current row" gets highlighted)
by hitting ENTER they are able to "see more details" of the given highlighted row
Questions:
Is there a browser-native way to achieve this?
Is there a way to do it without javascript?
So far:
This is done by using a <table> element with tabindex="0" on each <tr> element.
I'm now adding some javascript magic to make the click/enter user interaction trigger to show more details in another div.
Thanks all for the help.
This is about as close as I think you can get without javascript.
You need to use css tables and not HTML tables and set the a tag as a table-row. Then set the "href" of the a tag to a hidden div with the more info. Use the :target psuedo class to make the hidden info visible.
You can now tab through the rows. However you need to press Return to activate the link (at least in Chrome)
.table {
display: table;
}
.table>.head,
.table>a {
display: table-row;
}
.table>.head>span,
.table>a>span {
display: table-cell;
padding: 5px;
}
.table>a:focus {
background-color: #CCC;
}
.moreInfo>div {
display: none;
}
.moreInfo>div:target {
display: block;
}
<div class="table">
<div class="head">
<span>Id</span>
<span>Name</span>
<span>Date</span>
</div>
<a href="#data1">
<span>1</span>
<span>Some Name</span>
<span>9 Jan 2019</span>
</a>
<a href="#data2">
<span>2</span>
<span>Another Name</span>
<span>10 Jan 2019</span>
</a>
</div>
<div class="moreInfo">
<div id="data1">Some more info on the first item</div>
<div id="data2">Some more info on the second item</div>
</div>
I'm pretty sure that the CSS solution won't be accessible.
In fact the CSS solution is even probably going to make the accessibility less good compared to if you have been used a <table> even without any JavaScript or ARIA.
If you really can't use JavaScript for whatever reason, I would still advice to keep the <table>
If the data presented is really tabular data, screen reader users won't understand anything if you don't use a true <table>.
Some screen readers try to present CSS tables like if they were true HTML tables, but often they fail in doing it really well, and many screen readers don't do anything special so the user see a serie of divs and spans.
Additionally, keyboard and screen reader users are used to:
- tab once to get into the table, tab once more to get out of it
- up/down arrow to move from row to row inside the table
- left/right arrow to move between columns if it's relevant in your case
IF you really want something accessible, that's what you need to do. And it's perfectly undoable without JavaScript.
Why don't you want use JavaScript ?
I can not imagine another way without using javascript! Here is the answer to your question!
You have to use tabindex = "0". But to focus you would have to use javascript
<div>
<a href="#" tabindex="0">
<p>hi</p>
</a>
<a href="#">
<p>hello</p>
</a>
<a href="#">
<p>woah</p>
</a>
<a href="#">
<p>oops</p>
</a>
<a href="#">
<p>Love</p>
</a>
</div>
You can use tabindex for the table, it works perfectly fine
<form>
First: <input tabindex="1" type="text">
Third: <input tabindex="3" type="text"> <br>
Second : <input tabindex="2" type="text">
Forth : <input tabindex="4" type="text"><br>
</form>
Related
Ok, I've been trying to figure this out for a while, and not quite sure it's possible in pure CSS.
I'm trying to create a bit of custom styling on a page of FileRun links that I send to clients. Sending a bunch of subfolders of large TIFF images (I split them up to make the download manageable). Most clients can figure out that they should go into each subfolder and download them individually. However, the "download all" button appears on the main page of the link, and plenty of not so tech-savvy clients send me angry emails complaining that they hit the "download all" button, and can't open or download the 5GB zip file that FileRun creates of the entire main folder link.
An example of a page is here:
https://demo.filerun.co/wl/?id=T2Gv5oGiGMxO3welkXbaqs92fZ6meJmU
The main limitation is that FileRun is encoded in IonCube, so I only have access to the CSS file, so no way I can add javascript or PHP code.
I've been trying to find a way to write CSS to hide the DOWNLOAD ALL button <a class="actionBtn"> by changing the CSS to .actionBtn {display:none;} in the main link page, but not any subfolders. I have found you can tell when you are in a subfolder page when there is a 2+ level breadcrumb containing a carat.
e.g. in the 'elf' subfolder, this can be detected by the presence of the > in the breadcrumb, and the presence of <span class="bcSep">></span>
Is there any way to change the attribute of actionBtn or right div on the right, depending on the presence of the <span class="bcSep">></span> or number of elements in the breadcrumb?
The nesting order in the header div on the root page is:
<div class="left">
<a class="breadCrumb">xxx</a>
</div>
<div class="right">
<a class="actionBtn">DOWNLOAD ALL</a>
</div>
On any subfolders it is:
<div class="left">
<a class="breadCrumb">xxx</a>
<span class="bcSep">></span>
<a class="breadCrumb">xxx</a>
...
</div>
<div class="right">
<a class="actionBtn">DOWNLOAD ALL</a>
</div>
I've tried child selectors, but can't find a way to target the actionBtn or right element from the breadCrumb or left element... Any ideas or am I asking for the impossible from pure CSS?
Since all three of your products (colored, samba and skaven) as well as the DOWNLOAD ALL anchor link have unique URLS, you can just use the href attribute value to only select the anchor tag on the homepage using a css attribute selector like this:
a[href="http://someUniqueURL.com/"].actionBtn {
display:none;
}
Check and run the following Code Snippet for a practical example of the above approach:
/* CSS */
a[href="https://demo.filerun.co/?module=weblinks§ion=public&multidownload=1&id=T2Gv5oGiGMxO3welkXbaqs92fZ6meJmU"].actionBtn {
display:none;
}
<!-- HTML -->
<p>Homepage Link</p>
Download All
<hr/>
<p>Product 1</p>
Product 1
<hr/>
<p>Product 2</p>
Product 2
<hr/>
<p>Product 3</p>
Product 3
<hr/>
I am working on a glossary and have made a bulky file with terms in columns behind which are hidden texts (with display:none), in plain css/html.
Each entry looks like this in code: <div class=w tabindex=0>Achidrupa<div class=tt>Here follows hidden explanation.</div></div>
Instead of :hover I use :focus so the explanation is kept opened up in a sort of popup window, without use of Java or JS.
As there are entries with slightly different spelling I like to refer to the main entry, but not with the rather clumsy ‘‘See entry blah blah blah’’.
So, I like to make internal links, as we are used to with # and name or id in the linked-to element. But whatever I try, I cannot get another entry opened from the opened window with the link. Can I get some help with that? Very grateful for any solution.
I believe I did not make this issue clear enough from the start. I have the following code, including tabindex=0 and with .w:focus .tt{display: inline-block ; cursor:pointer; } in css.
<div class=w tabindex=0 name="alpha">1ste Entry Alpha <div class=tt>
Follows text as explanation on alpha which becomes visible after a click on Entry Alpha, otherwise it stays hidden with css display:none. [Probably about or 100 words here.]</div></div>
<div class=w tabindex=0 name="beta"> 2nd Entry on beta <div class=tt>
Follows text as explanation on beta which <a href=#alpha>link to entry alpha </a> after a click. [Probably about or 100 words here.]</div></div>
What I need is the possibility to open window 1st Entry Alpha when I click in opened window Entry on beta and click on ‘link to entry alpha’.
I am sorry but the delivered javascript code and snippet didn’t work. It would not open any focused element. By the way, the glossary works great in this way, except for the internal linking.
Here is a solution using javascript: get the hash, find element with corresponding name and focus it. The whole thing is wrapped in onload otherwise the browser wont focus the element.
window.onload = function () {
var hash = window.location.hash.substr(1);
if (hash) {
var target = document.getElementsByName(hash)[0].focus()
}
}
.w {
display: block;
color: black;
text-decoration: none;
}
.w > div {
display: none;
}
.w:focus {
outline: none;
}
.w:focus > div {
display: block;
}
<a name="q1" href="#q1" class="w">
Question ?
<div>mopm adsma pomfdsapoi mfadsp fasdm pasofdm pasdofi mdfs apfd smapfdso amfp ad</div>
</div>
<a name="q2" href="#q2" class="w">
Question ?
<div>mopm adsma pomfdsapoi mfadsp fasdm pasofdm pasdofi mdfs apfd smapfdso amfp ad</div>
</div>
<a name="q3" href="#q3" class="w">
Question ?
<div>mopm adsma pomfdsapoi mfadsp fasdm pasofdm pasdofi mdfs apfd smapfdso amfp ad</div>
</div>
I have a repeating partial view in an ASP.NET MVC 5 application that is showing up incorrectly in certain circumstances in Chrome. It's not happening in any other browser, and I'm at a loss to figure out what's going on.
My razor code is pretty straightforward -- just a foreach loop that calls #Html.Partial(). I'm going to skip it for now in the interest of saving space, but the HTML it produces looks like this:
<div id="dataDisplay">
<div id="dataRow39" class="list">
Edit
<span class="normal">AAA Test 1</span>
<span class="large">Test Description 1</span>
X
</div>
<div id="dataRow1" class="list">
Edit
<span class="normal">AHBA</span>
<span class="large">Arkansas Home Builders Association</span>
X
</div>
. . .
</div>
And the page itself looks like this:
When users click the "Edit" link, I use an AJAX call to replace a single div with a different partial view that has input elements for data-entry. That div also has a cancel button that triggers another AJAX call back to the original partial view. That produces nearly identical HTML, but one element gets positioned wrong.
<div id="dataDisplay">
<div id="dataRow39" class="list">
Edit
<span class="normal" style="">AAA Test 1</span>
<span class="large" style="">Test Description 1</span>
X
</div>
<div id="dataRow1" class="list">
Edit
<span class="normal">AHBA</span>
<span class="large">Arkansas Home Builders Association</span>
X
</div>
. . .
</div>
The only difference I can see is those empty style tags. They don't appear in the console when I debug my AJAX, and they don't appear in other browsers. But if I manually go in and remove them, it doesn't seem to fix the layout problem.
I realize I've left out a lot of details. I'm trying to keep this from being really excessively long. I can provide any of the missing details if needed. Does anybody have any idea what could be going wrong?
UPDATE: As I'm playing around with this a bit, I have a feeling it has something to do with the float:right on the .delete-button class. Here's the CSS for that class:
.delete-button {
float: right;
font-size: .9em;
text-align: right;
padding: 0 3px;
margin: auto 0;
color: #888;
}
I am using bootstrap (Twitter-Bootstrap 3) in a quiz style application and I use bootstrap buttons for the answers of the quiz. My problem is that sometimes the answers are quite long, and instead of wrapping the text to the width of the col that the buttons are placed in, the text just keeps going in one line and goes over the col and the width. Is there an easy way to fix this (Note that I canot define set widths as the length of the answers change)? Showing the code is a bit difficult, as it uses javascript to populate the answer buttons, but I will show a screen shot and the resulted populated HTML (after the javascript has populated the question and answers):
Here is the resulting HTML:
<div class="row">
<div style="float: none; margin: 0 auto;" class="col-sm-7">
<div class="panel panel-default">
<div class="panel-heading">Quiz 4 - This is the quiz 4 description</div>
<div class="panel-body" id="question" style="display: block;"><font color="#AAAAAA"><strong>Code: </strong>80559</font><br><br><font color="#888888"><strong>Instruction: </strong>Based on the provided correct answer, select the answer choice that correctly gives the required evidence from the text. Once the timer runs down you will be forced to move onto the next question.</font><br><br><div class="alert alert-info"><strong>Question: </strong>express a negative sentiment in humorous terms</div></div>
<div class="panel-footer clearfix">
<div class="row">
<div class="col-sm-1" id="submit"></div>
<div class="col-sm-11" id="answers" style="display: block;"><button onclick="submitAnswer(22)" class="btn btn-default btn-sm">negative sentiment: You couldn't pay me to watch that....that's how I feel / humorous terms: beach reading without the beach, airport reading without the airport...</button><br><br><button onclick="submitAnswer(23)" class="btn btn-default btn-sm">negative sentiment: they are just the wrong amount of time / humorous terms: they don't have the compressed energy of a short story</button><br><br></div>
</div>
</div>
</div>
</div>
I would think that bootstrap should be wrapping the button text within the div automatically, but it doesn't. I have been looking for solutions but I haven't been able to find anything that covers this problem particularly. Any help would be appreciated. I don't want to use <a href='#" ...> because it is important that the page not reload or be redirected when the button is pressed. Only the onclick function submitAnwers() should be called with no redirect.
The btn class in Bootstrap 3 contains 'white-space:no-wrap;', so the buttons will not wrap on mutliple lines. You can change this using a simple CSS override like:
.btn {
white-space: normal;
}
Demo: http://www.bootply.com/90082
This is an old question with an old answer. The answer solves the problem, but you can get ugly word breaks, where the button breaks in the middle of a word, seemingly wherever it wants to.
My answer forces the button to wrap between words, providing for a nice, clean, and responsive button.
.btn-responsive {
white-space: normal !important;
word-wrap: break-word;
}
Click Here
Hope it helps someone in the future.
I have always struggled designing css forms, I can never get the input and label side by side. Do you have any words of wisdom that may help me.
I usually use a 10px margin on the bottom but cannot get them aligned
My Common form:
Name:
Email:
Phone:
Message:
text area
I know I'm going to get backlash for this from people who think that the only possible way to do things is with pure CSS, divs, spans, etc. However, your form is tabular. You have a column of titles, and a column of input fields. In this case, because of the tabular layout, a valid solution could be tables.....GASP!
Tables are not valid for page layout...let me repeat that again, tables are not valid for layout. However, you've got an element of a page, you're not doing a full page layout. You can easily use <th> elements to style the labels for the inputs, which is quick and simple. Overall, the table (tabular) solution would be less verbose than many of the CSS layouts given, which from a pure HTML standpoint is a win. It will continue to work and layout properly even when the server gets backed up and can't load the external CSS document. To all those who believe that tables are never ok, let me remind you that this solution will validate with W3 100% of the time provided your table is properly structured. And it's far more cross browser compatible, with no box-model issues in the "crabby" legacy browers. Certainly continue to progressively enhance with CSS as is best practice.
Theory and practice, especially in the web world, are two entirely different things. In theory, all of us should be producing 100% HTML5/CSS3/Semantic/SEO Optimized...blah blah blah. In practice, theory only goes as far as the first customer complaint. Progressive enhancement is key to survival. When a webform breaks in a big corporate setting, money is lost and people get fired. For that reason, the International Bank I recently did work for had requirements that demanded all its webforms were tabular (assembled with tables) It's hard to argue with a portfolio of sites whose users generate the company hundreds of millions of $$$ annually.
<style>
ul.anyclassname{
padding:0;
}
ul.anyclassname li{
list-style-type:none;
clear:left;
}
ul.anyclassname li label{
width:300px;
float:left;
}
.inputs{
float:left;
}
</style>
<form>
<ul class="anyclassname">
<li>
<label>Name:</label>
<div div class="inputs"><input type="text"></div>
</li>
<li>
<label>Email:</label>
<div div class="inputs"><input type="text"></div>
</li>
<li>
<label>Phone:</label>
<div div class="inputs"><input type="text"></div>
</li>
</ul>
</form>
I usually do this:
<div>
<label for="txtname">Name:</label>
<input type="text" id="txtname" name="txtname"/>
</div>
<div>
<label for="txtEmail">Email:</label>
<input type="text" id="txtEmail" name="txtEmail"/>
</div>
<div>
<label for="txtPhone">Phone:</label>
<input type="text" id="txtPhone" name="txtPhone"/>
</div>
etc...
Then with my CSS:
label { width: 100px; display: inline-block; }
Something along those lines. Nothing fancy, but they are side-by-side and with the surrounding div you get a block level element to give you a line return after each pair.
I wrote a complete form in this answer: how can we make forms like this with css & html? . It has the html markups and the css classes you need to start.
The code is also in a fiddle here: http://jsfiddle.net/vSqR3/64/ (Now with the nice addition of the for attribute, thanks Kyle!)
You will find in that link not only how to put one markup next to the other, but how to set sizes and borders for each.
I strongly suggest you to play on the jsfiddle.net website. You'll be able to modify and test immediately all your changes.