Input effect on keyboard tab -> focus, but NOT on click - css

When a user 'tabs over' to an input, I want the focus effect to be normally displayed, but on click, I don't want it to be visible.
User hits tab, now focussed on toggle button, I would like the toggle button to have slight glowing outline, which I'm currently able to do.
Now,
User clicks on the toggle button or it's associated label, toggle changes as usual,
BUT, I want the glow to never appear in the first place, or to disappear as quickly as possible.
I know about .blur(), and right now I'm having to use a setTimeout for a lazy fix, but I'd like to know if there's a better way to accomplish this, or if there's possibly a CSS only solution

I think a lot of front-end developers struggle to find a balance between aesthetics and the best-practices for accessibility. This seems like a great compromise.
Here's how I do it. The idea is to toggle outlining on when the user uses the tab key and turn it back off when they click.
JS
document.addEventListener('keydown', function(e) {
if (e.keyCode === 9) {
$('body').addClass('show-focus-outlines');
}
});
document.addEventListener('click', function(e) {
$('body').removeClass('show-focus-outlines');
});
Styles
body:not(.show-focus-outlines) button:focus,
body:not(.show-focus-outlines) [tabindex]:focus {
outline: none;
}

I'm currently doing something similar for my company. Unfortunately you must use JavaScript since CSS doesn't support this use case.
Here's what I've done.
var btns = document.querySelectorAll('button');
var onMouseDown = function (evt) {
evt.target.dataset.pressed = 'true';
};
var onMouseUp = function (evt) {
evt.target.dataset.pressed = 'false';
};
var onFocus = function (evt) {
var element = evt.target;
if (element.dataset.pressed !== 'true') {
element.classList.add('focus');
}
};
var onBlur = function (evt) {
evt.target.classList.remove('focus');
};
for(var i = 0, l = btns.length; i < l; i++) {
btns[i].addEventListener('mousedown', onMouseDown);
btns[i].addEventListener('mouseup', onMouseUp);
btns[i].addEventListener('focus', onFocus);
btns[i].addEventListener('blur', onBlur);
}
* { box-sizing: border-box; }
body { background-color: white; }
button {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
min-width: 100px;
margin: 0 1px;
padding: 12px 10px;
font-size: 15px;
color: white;
background-color: #646e7c;
border: none;
border-radius: 5px;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.2);
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
button:focus { outline: none; }
button:active {
-webkit-transform: translateY(1px);
-moz-transform: translateY(1px);
transform: translateY(1px);
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.2);
}
button.focus {
font-weight: bold;
}
button.primary { background-color: #2093d0; }
button.success { background-color: #71a842; }
button.danger { background-color: #ef4448; }
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<button>Default</button>
<button class="primary">Primary</button>
<button class="success">Success</button>
<button class="danger">Danger</button>
</body>
</html>
Basically instead of relying on browser's native focus I add/remove a focus class on my button depending on the situation.

If you use the what-input.js plugin you can apply styles specifically for keyboard users. You can use the following code to highlight a button that has been tabbed to. I've found what-input to be a reliable plugin (comes bundled with Zurb Foundation) and is currently regularly maintained.
// scss
body[data-whatinput="keyboard"] {
button {
&:focus {
// other highlight code here
box-shadow: 0 0 5px rgba(81, 203, 238, 1);
}
}
}
or
/* vanilla css */
body[data-whatinput="keyboard"] button:focus {
box-shadow: 0 0 5px rgba(81, 203, 238, 1);
}

Related

How to create dynamic custom style on mat -dialog on each mat-table row with top triangle in Angular - Material

Here is my sample code.
Please find my working sample code here
I need to set triangle on right top corner in mat-dialog box - Angular.
I am getting top right corner triangle dialog box using static css on last row.
But here not able to get on each row on change request button click.
The below code is for the Dialog box Component
openDialog(Id, Currency, Amount, Reason, StatusDescription, payment, event) {
let targetAttr = event.target.getBoundingClientRect();
const dialogConfig = new MatDialogConfig();
dialogConfig.disableClose = true;
dialogConfig.autoFocus = true;
dialogConfig.data = {
Id: Id,
Reason: Reason,
StatusDescription: StatusDescription
};
dialogConfig.position = {
top: targetAttr.y + targetAttr.height + 10 + "px",
left: targetAttr.x - targetAttr.width - 20 + "px"
};
dialogConfig.panelClass = ['my-panel','arrow-top'];
const dialogRef = this.dialog.open(EditingDialogComponent, dialogConfig);
dialogRef.afterClosed().subscribe(
data => {
console.log("Dialog output:", data)
}
);
}
The Below code is from style.scss
/* Add application styles & imports to this file! */
#import "~#angular/material/prebuilt-themes/indigo-pink.css";
.my-panel {
overflow: hidden !important;
border-radius: 5px !important;
padding: 0px !important;
color: #fff;
}
.my-panel.arrow-top {
margin-top: 40px;
}
.my-panel.arrow-top:after {
content: " ";
position: absolute;
right: 100px;
top: 365px;
border-top: none;
border-right: 15px solid transparent;
border-left: 15px solid transparent;
border-bottom: 15px solid gray;
}
I am getting like this.
But I want dialog box with upper arrow on each row under change request button click event

Styling element in shadow dom

I have two custom elements
<desktop-canvas id="desktop">
#shadow-root (open)
<desktop-window>
</desktop-window>
<desktop-canvas>
I'm trying to style <desktop-window> like so:
#desktop::shadow desktop-window {
background-color: red;
padding: 25px;
margin: 25px;
display: block;
}
But desktop-window dosen't receive the style. What am I doing wrong? The same syntax seems to be working in this codepen (not by me): https://codepen.io/matt-west/pen/FtmBL
As announced here...
Starting in Chrome 63, you cannot use the shadow-piercing selectors ::shadow and /deep/ to style content inside of a shadow root.
According to that page you are only affected if you use Shadow DOM v0 components. You either use the shady DOM polyfill, switch to Shadow DOM v1 components or place the styles inside the component and use :host:
var XProductProto = Object.create(HTMLElement.prototype);
XProductProto.createdCallback = function() {
var shadow = this.createShadowRoot();
var img = document.createElement('img');
img.alt = this.getAttribute('data-name');
img.src = this.getAttribute('data-img');
img.width = '150';
img.height = '150';
img.className = 'product-img';
shadow.appendChild(img);
img.addEventListener('click', function(e) {
window.location = this.getAttribute('data-url');
});
var link = document.createElement('a');
link.innerText = this.getAttribute('data-name');
link.href = this.getAttribute('data-url');
link.className = 'product-name';
shadow.appendChild(link);
var styleEl = document.createElement('style');
styleEl.innerHTML = `
:host .product-img {
cursor: pointer;
background: #FFF;
margin: 0.5em;
}
:host .product-name {
display: block;
text-align: center;
text-decoration: none;
color: #08C;
border-top: 1px solid #EEE;
font-weight: bold;
padding: 0.75em 0;
}`;
shadow.appendChild(styleEl);
};
var XProduct = document.registerElement('x-product', {
prototype: XProductProto
});
body {
background: #F7F7F7;
}
x-product {
display: inline-block;
float: left;
margin: 0.5em;
border-radius: 3px;
background: #FFF;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
font-family: Helvetica, arial, sans-serif;
-webkit-font-smoothing: antialiased;
}
<x-product data-name="Ruby" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/ruby.png" data-url="http://example.com/1"></x-product>
<x-product data-name="JavaScript" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/javascript.png" data-url="http://example.com/2"></x-product>
<x-product data-name="Python" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/python.png" data-url="http://example.com/3"></x-product>
CSS Scoping Module Level 1 provides an answer to: Why is the shadow host so weird?:
The shadow host lives outside the shadow tree, and its markup is in control of the page author, not the component author.
It would not be very good if a component used a particular class name internally in a shadow tree stylesheet, and the page author using the component accidentally also used the the same class name and put it on the shadow host. Such a situation would result in accidental styling that is impossible for the component author to predict, and confusing for the page author to debug.

Make toggle behave like input controls i.e. to respond to space bar key down and keyboard tab action

We have toggle controls as in the below link
https://www.w3schools.com/howto/howto_css_switch.asp
While these take input on mouse click, they don't change state on space key down and when keyboard tab is used these are not highlighted/selected.
How can these be made behave like any regular input control?
I would look for solution in html/css which could be easily applied to any such controls.
Update:
As mentioned in the answer, checkboxes change state on press of spacebar and not enter key.
I found the answer. First add a tab index to the element, so it can be focused. Then you can add this jQuery code.
$('.switch').on('keydown', function(e) {
if(e.keyCode == 13) {
if($(this).children("input").attr('checked')) {
$(this).children("input").attr('checked', false);
} else {
$(this).children("input").attr('checked', true);
}
}
});
I edited the code W3Schools site to add this code. You can view it at https://www.w3schools.com/code/tryit.asp?filename=FHPJRINMFQOH.
Good Luck!! Hope this helps!!
This can be done with css. Since we have to guess how your html and css is structured, i can only provide you something you can work with.
And by the way you change checkbox state with spacebar, not with enter key
label { margin-right: 1rem }
span {
display: inline-block;
width: 2rem;
height: 2rem;
background: rebeccapurple
}
input:focus + label span {
outline: 1px solid red
}
input:checked + label span {
background: red
}
/* https://css-tricks.com/places-its-tempting-to-use-display-none-but-dont/ */
.visuallyhidden {
position: absolute;
overflow: hidden;
clip: rect(0 0 0 0);
height: 1px; width: 1px;
margin: -1px; padding: 0; border: 0;
}
<input id="check" class="visuallyhidden" type="checkbox">
<label for="check"><span></span></label>
<input id="box" class="visuallyhidden" type="checkbox">
<label for="box"><span></span></label>
This can done using jquery
Since the toggle button is a simple checkbox we can access them using the keypress function
$(document).ready(function(){
$('#mycheckbox').keypress(function(event) {
var keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == 13) {
clickCheckBox(this);
}
event.stopPropagation();
});
});
function clickCheckBox(box){
var $box = $(box);
$box.prop('checked',!$box.prop('checked'));
}
find the fiddle here

Unable to click checkboxes after styling

I have tried to style some checkboxes but now I can't click on/ activate/ check them. Radio buttons that are mostly styled the same way do work.
$(document).ready(function() {
var $selection = $('.sc-checkbox');
$selection.each(function() {
var $this = $(this),
$id = $this.attr('id');
$this.after( '<label for="' + $id + '"></label>' );
});
});
input[type="checkbox"].sc-checkbox {
-webkit-opacity: 0;
opacity: 0;
left: -102%;
position: absolute
}
input[type="checkbox"].sc-checkbox+label{
padding: 0 5px 0 10px;
}
input[type="checkbox"].sc-checkbox+label:before {
content: '';
display: inline-block;
background: transparent;
border: .14286rem solid rgba(0, 0, 0, 0.54);
width: .92857rem;
height: .92857rem;
border-radius: .14286rem;
font-family: 'Material Icons';
position: relative;
vertical-align: middle;
left: 0;
line-height: .92857rem;
-webkit-transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1);
transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1)
}
input[type="checkbox"].sc-checkbox:checked+label:before {
background: #3f51b5;
border: .14286rem solid #3f51b5;
content: '\E5CA';
color: #fff
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<input type="checkbox" class="sc-checkbox" id="test"></label><label for="test">Test</label>
<input type="checkbox" class="sc-checkbox" id="test1" checked></label><label for="test1">Test1</label>
When you run the example everything works but on my website it doesn't work.
I have fiddled around with positions, paddings and margins on the :before but nothing seems to be working.
I hope someone can help me make the checkboxes work again.
Thanks in advance.
You have a code that fixes a bug when text field isn't selected when label is clicked:
textfields.js, line 30:
// Fix bug that text field isn't selected when label is clicked
$('label').click(function() {
var $id = $(this).attr('for');
$('#'+$id).trigger('click');
});
However this code cause your click on the label to be triggered twice, so you get two clicks on the checkbox (which causes your checkbox to be checked and then unchecked immediately, or the opposite).
I'm not sure if you really need this code or not, but you can change your fix-bug to something like this:
// Fix bug that text field isn't selected when label is clicked
$('label').click(function() {
var $id = $(this).attr('for');
if ($('#'+$id).is(':checkbox')) {
return;
}
$('#'+$id).trigger('click');
});

How to set background color to $actionsheet in ionic frameworks

Here is the code, very simple and copy paste from office website
$scope.show = function() {
// Show the action sheet
var hideSheet = $ionicActionSheet.show({
destructiveText: 'Delete Photo',
titleText: 'Modify your album',
cancelText: 'Cancel <i class="icon ion-no-smoking"></i>',
cancel: function() {
// add cancel code..
},
buttonClicked: function(index) {
return true;
}
});
// For example's sake, hide the sheet after two seconds
$timeout(function() {
hideSheet();
}, 2000);
};
I want to change the cancel button have a red color background, how I can achieve it in ionic frameworks?
Easiest way is to look at the markup using your browser (after running ionic serve in your terminal), for example in Chrome ctrl+shift+i, where you can choose the button and see what classes are attached. In your case you'll see something like this:
<div class="action-sheet-group action-sheet-cancel" ng-if="cancelText">
<button class="button ng-binding"
ng-click="cancel()"
ng-bind-html="cancelText">Cancel</button>
</div>
Which has styles that for the parent div, and child button something like this:
.action-sheet-group {
margin-bottom: 8px;
border-radius: 4px;
background-color: #fff;
overflow: hidden;
}
.action-sheet .button {
display: block;
padding: 1px;
width: 100%;
border-radius: 0;
border-color: #d1d3d6;
background-color: transparent;
color: #007aff;
font-size: 21px;
}
Just change these values either in Sass or directly in your styles sheet if you're not using Sass.

Resources