CSS box-shadow vs outline - css

I have not been able to find a duplicate and you can find a bunch of blog posts which suggest to use box-shadow for element's focus state instead of outline as it is more flexible in terms of styling and it also follows the border-radius of the element you are styling unlike outline which always stays rectangular.
Is it considered a good practice to replace outline with box-shadow? Are there any caveats of doing so?

There is a serious caveat to using box-shadow as a focus indicator. It doesn't work in Windows high-contrast themes.
When a Windows high-contrast theme is turned on, web browsers which support it will override certain CSS properties. Firefox, IE, and Edge do this, but Chromium-based browsers don't (as yet).
Foreground colours are overridden, to match the Windows theme. This applies to text, borders, and outlines.
Note that the CSS transparent keyword is a colour value, and it is also overridden here. A transparent border becomes visible.
Background colours are overridden, to match the Windows theme.
Background images are removed (including CSS gradients) in IE and Firefox.
Edge preserves background images, but applies a solid background colour to text. So parts of the background image may not be seen.
box-shadow is not applied, so it won't work as a focus indicator.
The following focus style will NOT be seen when a Windows high-contrast theme is in effect:
a:focus {
box-shadow: 0px 0px 5px 5px rgba(0,0,255,1);
outline: none;
}
There is an approach which can work however. Instead of removing the outline entirely, make it transparent while leaving the outline style and width in place. When a Windows high-contrast theme is in effect, box-shadows won't appear, but the outline will appear because the transparent colour is overridden.
a:focus {
/* Visible in the full-colour space */
box-shadow: 0px 0px 5px 5px rgba(0,0,255,1);
/* Visible in Windows high-contrast themes */
outline-color: transparent;
outline-width: 2px;
outline-style: dotted;
}

Is it considered a good practice to replace outline with box-shadow? Are there any caveats of doing so?
The WCAG has a specific failure for that:
F78: Failure of Success Criterion 2.4.7 due to styling element outlines and borders in a way that removes or renders non-visible the visual focus indicator
Note that users may want to customize their own outline indicator for their own particularity (better contrast, specific color, size, ...). So by removing it and replacing it with box-shadow, you won't let their own settings take precedence over yours.

Related

styling: how to override primeng tabmenu border-colors on active element

I currently have a global blue theme (saga-blue). I managed to change the text and bottom border color (to match the desired brand colors) by using simple css.
However, when a menu item is first selected, it gets this ugly blue-colored border behind it, as such:
https://imgur.com/SYF7xmJ
No matter what CSS I try, I can't manage to remove it. I can't find where it comes from when I inspect the element. Also, it gets removed as soon as I click anywhere else on the screen: it is just there for the first click on the item, goes away after any other click.
CSS that I have tried:
.p-tabmenu .p-tabmenu-nav .p-tabmenuitem.p-highlight .p-menuitem-link {
color: $brand-red;
border-left: 0px !important;
border-right: 0px !important;
}
.p-tabmenu .p-tabmenu-nav .p-tabmenuitem.p-highlight {
color: $brand-red;
border-left: 0px !important;
border-right: 0px !important;
}
I also tried unsetting any property that had to do with 'left' or 'right' on the menuitem and menulink components - but the ugly blue border just keeps on showing. If anyone has any idea what kind of property this might be, I would really appreciate it.
If your style is not applied and you want to override the primeng default styling, you may need to use :host ::ng-deep.
Another way of applying style to a PrimeNG component nested element, is to use the styleClass template property. It is not everytime efficient, you need to sometime force the css through the !important priority modifier. It is not the cleanest way, but there is few CSS properties that are inlined by calculation on some component.
For your specific problem, the .p-tabmenu (and subclasses) is playing with a mixin of focus, when the element is in focus state.
#mixin focused() {
outline: $focusOutline;
outline-offset: $focusOutlineOffset;
box-shadow: $focusShadow;
}
You need to play with the property box-shadow to remove/modify this blurred color that you dislike with the advices I gave you on the primeng styling if it is not applied as you wished.
Don't forget the pseudo-class :focus while overriding the style.
You may have this kind of result to remove it completely.
:host ::ng-deep .p-tabmenu .p-tabmenu-nav .p-tabmenuitem.p-highlight .p-menuitem-link:focus {
box-shadow: none;
}
Try outline: 0 this is something that defaults browsers do for accesibility mainly.

Tapping links in iOS Safari shows a thick white border around element - how to get rid of it?

Problem
On my site I see this super strange behaviour on any kind of linked elements (text, images, svg elements, table cells): when long tapping them in Safari on iOS, a thick white border appears before showing the link preview.
What I have tried so far
As it's only showing on iOS, I am a bit limited with debugging it, unfortunately.
I have tried to fix it using the following most recommended solutions with link tap in iOS Safari, but neither of them does solve the issue:
html {
-webkit-tap-highlight-color: transparent;
}
a, a:visited, a img {
-webkit-background-clip: content-box;
}
input, textarea, button, select, label, a {
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-tap-highlight-color: transparent;
}
Solution ideas?
Does anybody know, or has an idea, how I can get rid of this border - or at least also make it appear "transparent"?
Much appreciated!
RESOLVED: seems like the thick white border is not the border, but related to the background color of the element / linked element. And it is controllable through the :active state.
Fixed by adding this to my CSS:
a:active {
background-color: transparent;
}
Solution inspired by the answer here: https://stackoverflow.com/a/12686281/5750030

Moz padding behaving differently on buttons

On all my buttons the padding is behaving differently in firefox. From research I know this is because FF has some strange settings in the default stylesheet but I have added the general fix into my stylesheet. That's fine and I can live with that apart from one button will not fit into the toolbar in firefox because the padding makes it too big.
Jsfiddle here.
Usual fix;
input[type=button]::-moz-focus-inner{padding:0; border:0;}
The css for the button with a few things removed;
.buttonBlue {background-color:#008abd; border-radius:0.2em;
font-family:inherit;
color:white; border: 1px solid black;
cursor:pointer;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#008abd', endColorstr='#036b91');
background: -webkit-gradient(linear, left top, left bottom, from(#008abd), to(#036b91));
background: -moz-linear-gradient(top, #008abd, #036b91);
}
If you set an element's appearance attribute to none, any well-behaved browser will drop its gui flavor.
https://developer.mozilla.org/en-US/docs/CSS/-moz-appearance
For buttons, the default value for appearance is "button". Setting it to "none" explicitely should override the browser's built-in platform-native styling, including weird padding.
Firefox is not the only browser reacting to this attribute: Safari and Chrome listen to the -webkit-appearance variation, and Opera listens to the -o-appearance variation. I don't know about MSIE9 or 10.
I have found a fix by targeting moz with a css prefix. It's not ideal but it works and I need to move onto other things rather than worrying about a button! Here it is anyway.
#-moz-document url-prefix(){
.buttonBlue
{ padding:0px 7px 0px 4px !important;}
}

Load sections of a css file depending on the browser

There are buttons on my website that look overly skinny in Chrome compared to Firefox. The button's HTML looks like: <button name="shutdown" type="submit" value="df" class="boton"> Press </button>
My CSS attempt looks like:
.boton {
font-size: 17px;
color: #000;
background: #ee3333;
background: rgba(225, 50, 50, 0.6) !important;
font-family: lucida console;
border: 1px solid #FF4444;
padding: 2px;
-moz-border-radius: 7px;
border-radius: 7px;
cursor:pointer;
}
.chrome .boton
{
padding: 5px !important;
}
I'm not sure if I'm doing this right. ".boton" does indeed change the style of the button, but the padding doesn't change in Chrome. What's wrong here?
The reason that the padding isn't applying to the element is due to the fact that there is no chrome class assigned to any element. There are various hacks around certain Vendor-Specific styles, see this article, but no browser applies a class of .chrome or .moz or anything like that.
However, to achieve more "horizontal" padding, you can use the -webkit-padding-start(padding-left) and the -webkit-padding-end(padding-right). Currently I do not believe there is full padding, or vertical padding for these yet. Be sure when using these to write the -webkit-padding-start, or whichever rule you use, after your padding rule. Otherwise the latter will overwrite the former and both will be lost.
Unless you've also added some browser sniffing that adds the class .chrome etc. to the body that class has no effect.
On the other hand the box model of Firefox and Chrome is not radically different, but the defaults for padding, border, margins etc. may be different. Just explicitly set those values and they should most likely render the same (give or take a few pixels because of different rounding errors). You should not need to add custom css for each browser (but if you use experimental css features like -moz-border-radius and -webkit-border-radius with vendor prefixes you should use all of them in at the same time; the others will ignore the unknown properties).
The different versions of IE (Internet Explorer) do have a radically different box models, and if you cannot get some version of IE to render something correctly with the standard css you should use conditional comments to include IE specific css overrides after the main css file.

text-decoration: underline vs border-bottom

What is the difference to use {text-decoration: underline} and {border-bottom: ...}?
which is easy to style and cross browser compatible?
when we should use border-bottom over text-decoration: underline?
Would it be good to use border-bottom always in place of text-decoration: underline?
border-bottom puts a line at the bottom of the element box. text-decoration:underline renders the text underlined. The exact difference depends on the HTML and text layout engines in use, but in general if you want text underlined, then underline it.
Sorry to say this, but some answers here are misleading. Splitting a line of text does not place the border at the bottom of the entire block, because of the nature of inline blocks. Borders under links are actually more consistent across browsers than text-decoration: underline.
See: Text-Decoration vs. Border-Bottom
As Ignacio said, border-bottom will put the line at the bottom of the containing box, whereas text-decoration:underline will actually underline the text. This becomes an important distinction for multi-line strings.
I am a single line and will look similar for both methods
---------------------------------------------------------
would probably render the same for both styles, but you'll get the following for multi-line strings.
I am a string that has been
split and added a border-bottom
-------------------------------
I am a string that has been
---------------------------
split and underlined
--------------------
Apologies for using code formatting rather than properly rending these examples, but you can see the point I'm trying to make.
bottom-border lets you control the distance between the text and the underline, so its more versatile. And (as mentioned above) it allows a different color for the underline (although I don't see a reason why you'll want to do that).
text-decoration is more 'correct' because it is the 'real' CSS property meant for underlining text.
if you set text-decoration: underline for all links then you will have to set text-decoration: none for special links which you don't need an underline. but if you use border-bottom instead, you'll save one line of CSS code (provide you set text-decoration: none in your reset CSS.
so all in all, i'll vote for border-bottom if you have a complex layout with different styles for each link but text-decoration for a simple website coded 'by the book'.
While there are always going to be cases where one is more appropriate than the other, border-bottom offers much more precise control over text-decoration and is therefore probably the preferred method. Here's a quick (likely not exhaustive) list of properties that border-bottom can control/enable that text-decoration cannot:
Spacing between text and "underline"
"Underline" style (dotted, dashed, solid, gradient, image)
Thickness
CSS transitions/animations
Separation of color between text and "underline"
In many cases, most of these abilities will not be needed - but it is good to have them available! I've switched to using border-bottom primarily for the ability to put a few pixels of padding between the text and the underline; the next most common use I've found is divorcing the underline color from the text color.
With CSS variables now shipping in every major browser, a "reset" stylesheet might look something like this:
:root {
--link-color: blue;
--hover-color: purple;
--underline-color: var(--link-color);
}
a {
color: var(--link-color);
text-decoration: none;
border-bottom: 1px solid var(--underline-color);
}
a:hover {
color: var(--hover-color);
border-bottom-color: var(--hover-color);
}
This way, links will display as expected on a "default" basis, yet still allow for customization as needed.
setting your text to display inline (actually, it should be that by default) will cause the border-bottom to render much as a text-decoration rule.
however, i presume that you want to use this technique on links by doing the following:
/* my super eye catching dual colour link */
a {
color:black;
border-bottom:1px solid red;
}
which is all well and good, but you'll find that wherever you have an img tag inside a link, the image will have a red border under it.
if you can figure out a way to target the parent of a page element (the image) using existing selectors and no javascript, i'll buy you a beer but i don't think you'll have much luck.
using "text-decoration" avoids this issue altogether as an image is clearly not text, it will not render an underline when inside a link.
if you have complete control over your markup, i suppose you can bumble your way through by adding classes to every link, but if you're working with any popular CMS system, you're going to struggle with this idea.
Try this border with 1px image
a:hover {
background: url("img/bg-link-hover.png") repeat-x scroll 0px 92% transparent;
background-color: transparent;
background-image: url("img/bg-link-hover.png");
background-repeat: repeat-x;
background-attachment: scroll;
background-position: 0px 92%;
background-clip: border-box;
background-origin: padding-box;
background-size: auto auto;
}

Resources