Cross-Browser Transparent Letters - css

I am creating a blog, and on the top of the blog is an image of some scene (I used a picture of NYC) with the text of the most recent blog post over top of it. I thought it would be really cool to have the letters have an outline, but can still be transparent so the viewer can still see the image.
I tried text-shadow with a transparent color, but all I got was a black letter (which I didn't expect but makes sense). I ended up using the webkit-text-stroke property, which isn't cross browser at all. I've attached an image of it in both Chrome and Firefox, with a text shadow behind it so you can see how a text shadow appears (kind of) without a color present.
Is there a way to have the desired effect (a border around the text, but no color) in modern browsers? For IE9 and down I'll just use a solid black color so.
This is the code I'm using to get the below effect:
figcaption {
position: absolute;
bottom: 0px;
left: 20px;
font-size: 90px;
color: transparent;
-webkit-text-stroke-width: 5px;
-webkit-text-stroke-color: #1F1F1F;
text-shadow: 1px 1px 5px rgba(255, 255, 255, 0.5);}
Thank you.

A couple of thoughts.
This example isn't exactly what you have described, but the result is good and should work well cross-browser:
http://jsfiddle.net/panchroma/JHvgp/
The key CSS is
h1.figcaption {
color:white;
position: absolute;
bottom: 0px;
left: 20px;
font-size: 90px;
opacity: 0.35;
filter: alpha(opacity=35);
text-shadow: 2px 2px 2px #000;
}
Alternatively, maybe it's possible to do something with with sIFR ... not sure about this though.
Good luck!
EDIT
Good suggestion from Adrien Be below -- with improved cross-browser transparency code:
http://css-tricks.com/snippets/css/cross-browser-opacity/

[I have no real ready-to-use solution here; but my thoughts on this are getting too long for a comment, so excuse me for putting this here.]
Cross-browser that’s kinda hard to achieve. I’ve looked into ways to get this kind of effect as well (and wasn’t satisfied with having it work webkit-only), and I came up with stuff like using dynamically created Canvas or SVG images that I draw the text on and then manipulating alpha values (canvas) or applying mask/filter effects (SVG).
But it’s a bit of a challenge to get the font rendering/positioning exactly right, and when text has to flow over multiple lines it gets even more complex. Best way I found for that is to split up the text into multiple span elements, one for each word; and then I place a Canvas or SVG image containing just that word as a background image for the span element. Big advantage here: The browser still takes care of text flow, like where to break text into a new line etc., because that’s a bit of a hassle to implement yourself in Canvas or SVG. And text flow also automatically adapts if the area the text gets displayed in changes size (f.e. user resizing browser window). What needs a little extra care is handling text resizing after the effect is applied – when user changes font size in their browser, the text I painted on my image might not fit any more – although using SVG and relative units that can be handled quite automatically as well. The other workarounds are either using background-size to scale the background image to the size of the span containing the word, or somehow capture that resize-“event” and re-draw images dynamically.
Using background images has the advantage that I can still keep the original HTML text in place – just setting it to transparent, so that when the user f.e. starts selecting text on the page it will still show up as actual text and is copy&paste-able.
But for a small effect like this it’s quite a lot of work … so I decided in the end to give up on that, and postponed using “transparent letters” until browser support for easier solutions like the webkit one you mentioned gets wider.

Related

sr-only class causing page scroll

I want to make some content available to screen readers but not visible on the page. Taking it off the page result in screen readers not announcing it, so I'm using a common hacky workaround, the sr-only class, used for instance by Bootstrap. Here's Kitty Giraudel's version:
.sr-only {
border: 0 !important;
clip: rect(1px, 1px, 1px, 1px) !important;
-webkit-clip-path: inset(50%) !important;
clip-path: inset(50%) !important;
height: 1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important;
white-space: nowrap !important;
}
The problem is with the position: absolute rule, which necessitates a parent with position: relative. Without it, the invisible content may end up at the bottom of the page and cause the browser to add scrollbars. I don't like having to have to add that position: relative rule on top of the sr-only class. It can easily be forgotten or accidentally removed. It would be easier if adding the class was the only needed step, which seems possible by simply adding top: 0 to these rules. But I'm a little nervous tweaking with such ancient wisdom. Is there a reason why it's not commonly done this way? Am I missing a potential issue with top: 0?
Short Answer
No, do not use top: 0
Longer Answer
First the issue you linked in the comments is using a very broken (and old as far as I can tell) screen reader only class, I think it has been updated (and if not then that just reinforces my opinions on using Font Awesome! 🤣).
The screen reader class you linked is identical to the visually hidden text class I created / use (which just shows if two of us came up with the same thing it might just be right!) and should not cause the issue described as it uses clip-path: inset(50%).
clip-path: inset(50%) effectively makes the element 0px high and 0px wide, so you should never get any overflow issues because of it.
Also the scroll bar issue tends to be caused by the margin: -1px part (which you notice we aren't using in our classes), but without something to test against I cannot confirm that is the case here.
As for adding top: 0 don't do this - you are indeed wise to not mess with old wisdom.
The second you start moving the position of the element some screen readers will try and compensate for the positioning (thinking that you are a bad developer and using absolute positioning to change the order of things on the page instead of changing DOM order), resulting in strange reading orders.
I have used the class I linked for 2 years now without ever seeing any unexpected scroll bars so you should be safe.
With all that being said, if you do manage to put together a codepen / fiddle etc. that demonstrates the issue you described with the class I recommend or the class in your question then please let me know as that is something I would want to address!
Final thoughts
In the bug report you linked in the comments, do not do as the final message suggests:
Size the element such that it is 0xN, or Nx0 (e.g. "width: 0" or similar).
Make the element "display: none".
Surround the element in a 0x0 div which is also "position: absolute".
All 3 of the above options would render the text completely invisible to a screen reader user (remove the element from the accessibility tree) and completely break the point of using a screen reader only class.
Options 4 and 5 are feasible options though:
Make "viewport-router" a containing block (e.g. "position: relative" or similar).
Change the "viewport-main" to "overflow-y: hidden" or similar.

Creating a browser agnostic or IE alternate internal button border for focus? (accessibility related)

Couple extra requirements I'm working under:
Needs to be reactive/mobile friendly
Needs to also be compatible with chrome, firefox, and ideally opera.
<button class="outline">
Lol A button
</button>
button{
background-color: blue;
color: white;
padding: 15px;
}
.outline:focus{
outline: 2px solid white;
outline-offset: -6px;
}
JS Fiddle example of what I'm doing now
Edit:
JS Fiddle Example of the trouble I'm having with past similar question answers
If you take a look at the second link and tab through the examples, possibly try changing some of the internal borders in the box class, you'll see that this option is pretty rigid, and I have failed to get a proper offset inner border with a sufficient gap from the outside edge.
In particular, 2px would probably be the minimum gap between the inner border and the outer edge. The intended use is like 4-6px in, so that there is a really clear border so I can create a 7.5:1 contrast ratio for high visibility of the focus box. In my particular use case, this is not possible with an external border without breaking the site color scheme, so it's really undesirable.
I'm kind of dubious about getting this to work as a generic solution across 3+ types of buttons as well, and also looking nice on mobile.
Additionally, if the correct answer here is just, "that's impossible you need to do something else entirely," that's fine as long as it really is true. I don't have the CSS experience to know for sure.
I was never able to find a solution like what I was looking for. Instead I ended up doing this:
box-shadow: 0 0 0 2px rgb(255, 255, 255),
0 0 0 4px rgb(0, 84, 164) !important;
outline: none !important;
Basically, you have to use a box shadow to mimic an outline, so I used two box shadows that match the colors/look of the button to create the same effect with an expansion of the button. This meets accessibility contrast requirements by sandwiching a color band in between the button and the outer band. As long as this inner band and the button are different enough in contrast, and the outer band matches the button, or another high contrast color.
Not really what I wanted, but there's not a lot (any) of other options that work in the context of this problem (older IE compatibility) unfortunately.

Random shadow appears out of nowhere on supposedly square elements, making everything misalign

I am trying to create a very precise matrix on top of a board. I know it's 48cm tall and wide, and therefore I am using the metric system. According to my code, they should align perfectly, but I'm experiencing some weird issues, which might be related to anti-aliasing. I honestly have no idea.
Take a look at this screenshot:
and then at this code: https://jsfiddle.net/o21rdwvw/3/
I use two methods:
background: black;
//one of these according to horizontal/vertical
width: 4px;
height: 4px;
and
outline: 4px solid black;
As you can see in this image, that is not really the case. It looks like some of the boxes has a shadow, with the HEX color #576c73, which has no relation to the color #000000 (unless the browsers somehow pick a shadow, which is some % brighter or darker than the original color).
I have tried changing the units around to pixel (even and odd numbers) as well as remove the transform: scale(), but none of them changed anything.
What kind of wizardry is this, and how can I prevent them from messing up my alignment?
EDIT: As you can see, the small boxes are differently sized, even though all the browsers report they're the same size. The bottom one is square, whereas the top and middle ones are slightly shorter:
EDIT 2: It appears to be a browser problem. Edge does not render the actual shadow, for example. It's just not as tall or wide as the others.

Google Style Toolbar CSS/HTML

I am trying to recreate that Google-style toolbar on G-mail and a few other Google services.
I have tried doing this as both a formatted list and nested div elements in one container but I have the same problem each time.
When you mouse over, the new 1px border moves all the other elements around and I have to apply stuff like:
left: -1px;
bottom: 1px;
Which is all well and good for the element currently :hover'd, all the rest move around and it looks ugly.
So I guess my question is:
Is there any way to display things such that a new 1px on :hover, will not alter the positioning, while still displaying these elements WITHOUT absolute positioning.
Obviously if the only avenue is absolute positioning where I have to put in pixel co-ordinations then sure, but there has to be a more elegant way.
You can do several thing to avoid the 1px border shifting things around on hover.
http://jsfiddle.net/ZeikJT/tBmm2/
One solution is to add a transparent border (border:1px solid transparent) so that there is always a gap. This will work in pretty much all situations. It also allows you to then simply change the border-color on hover and not re-specify the border-width so you won't ever need to make changes in two places if you decide to change the width.
http://jsfiddle.net/ZeikJT/NkBwp/
Another solution is to add a margin or padding that then gets taken out on hover. This is a little trickier to get working properly but can work just as well.

custom down arrow buttons using CSS in Qt

We're developing a touch screen Qt application in C++ forms that requires a wide down arrow graphic image as well as a custom background. I've been trying to get something that works using QSS, but have thus far been defeated.
The only way I found to get a wide button (one larger than 16 pixels) is to use negative margins:
QComboBox {
min-height:63px;
max-height:63px;
margin-right:47px;
border-image:url(Resources/ComboBox_Center1.png);
font-family: "Franklin Gothic Medium";
font-size: 22px;
}
QComboBox::drop-down {
width:47px;
border:0px;
margin:0px;
margin-right:-47px;
}
QComboBox::down-arrow {
image:url(Resources/ComboBox_Right1.png);
}
This puts the button at the correct position and makes the input area the correct size, but then the down arrow only opens the combobox, not open and then close.
All other options either extend the input area onto the area (margin, border) or shrink the entire control.
Setting the background-image tag had no effect - only the border image showed the image.
Note that the border image (or background color) always shows up even under the arrow.
Is there some way to style just the input section of a combo box? It seems like that portion of the combo should have its own child selector, but I haven't seen it.
Try this...
QComboBox {
min-height:63px;
max-height:63px;
font-family: "Franklin Gothic Medium";
font-size: 22px;
padding: 1px 1px 1px 1px;
}
QComboBox::drop-down {
width: 47px;
border: 0px;
}
QComboBox::down-arrow {
image: url(Resources/ComboBox_Right1.png);
width: 42px;
height: 42px;
}
Note: the width and height on the down-arrow image will depend on the image you are using. These work for my image.
There are some weird things about style-sheets - and a lot of hidden tricks. It might be worthwhile taking a few minutes to go through this which describes the basic principles behind how style sheets work. They seem easy, but even after using them for a while, I often go back to the examples and documentation.
Background images are one of those things that is not obvious. Here is something I took directly from the doc. In most cases when setting an image for the background what we really want is to set the border-image. I'm assuming the reason you don't see the "background-image" is that the combo-box is a "complex" widget - meaning that it is made up of a few others - and so that background is hidden behind them.
It is common to try the background-image property, but this has a
number of drawbacks: For instance, the background will often appear
hidden behind the button decoration, because it is not considered a
background. In addition, if the button is resized, the entire
background will be stretched or tiled, which does not always look
good. It is better to use the border-image property, as it will always
display the image, regardless of the background (you can combine it
with a background if it has alpha values in it), and it has special
settings to deal with button resizing.
As for styling the input area... assuming your QComboBox is editable, the input area is just a QLineEdit. So you could always assign a style sheet to the line edit this way
comboBox->lineEdit()->setStyleSheet(your style sheet);
I hope that helps.

Resources