I have an video tag with an div displayed on top. The div is pretty nice looking and visible for the most part, only dark images are a bit problematic.
For the sake of testing I searched out 3 pictures and overlayed them with my div.
The question is, how would someone create this overlay layout, so it is discreetly and clearly visible at the same time?
The result is as follows:
Visibility good!
Visibility bad
Visibility okay, background visibility bad
.container{
position: relative;
}
img{
width: 100%;
height: 100%;
}
.tag{
position: absolute;
bottom: 5px;
right: 0;
color: white;
font-size: 48px;
padding: 5px;
-webkit-border-top-left-radius: 20px;
-moz-border-radius-topleft: 20px;
border-top-left-radius: 20px;
background-color: black;
opacity: 0.4;
filter: alpha(opacity=40); /* For IE8 and earlier */
}
<div class="container">
<img src="https://www.nasa.gov/sites/default/files/20140824_0304_171.jpg"></img>
<div class="tag">Hello Tag</div>
</div>
<div class="container">
<img src="https://alifebeyondrubies.files.wordpress.com/2013/03/walls01.jpg"></img>
<div class="tag">Hello Tag</div>
</div>
<div class="container">
<img src="http://photos.epicurious.com/2015/01/12/54b4006b2413537c0d45738f_51143820_spaghetti-mussels-white-beans_6x4.jpg"></img>
<div class="tag">Hello Tag</div>
</div>
Although perhaps better suited for UX.SE, there are a couple of options I might offer.
Firstly, don't use opacity for the whole element, use a transparent background color to allow the white text to stand out.
Secondly, outlining the black(ish) tag in white (or a transparent white) will allow the element to be more visible on darker backgrounds but not affect those with lighter colors.
JSfiddle Demo
.tag{
position: absolute;
bottom: 5px;
right: 0;
color: white;
font-size: 48px;
padding: 5px;
-webkit-border-top-left-radius: 20px;
-moz-border-radius-topleft: 20px;
border-top-left-radius: 20px;
background-color: rgba(0, 0, 0, 0.4);
box-shadow: -1px -1px 0px 0px rgba(255,255,255,0.3);
}
IMHO, make the text white and add a drop shadow.
.tag {
color: #fff;
text-shadow: 0 1px 10px rgba(0,0,0,0.75)
}
Apparently you are concerned that one hardcoded background color does not suit all dark, neutral and light backgrounds.
There is a relatively new CSS property called background-blend-mode which controls how two backgrounds are blended with each other. You can use this property to specify a blending mode that produces some contrast in all situations.
The downsides:
Both image and overlay must be part of an element's background (mix-blend-mode is a better option with lesser support)
The overlay color must be chosen stategically. In the following example I used transparent white instead of transparent black since difference filter does not affect black color.
.photo {
position: relative;
height: 200px;
background-blend-mode: difference, normal;
}
.photo span {
position: absolute;
left: 0;
right: 0;
bottom: 0;
font: bold larger/50px sans-serif;
color: rgba(255, 255, 255, 1);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.photo-1 {
background:
linear-gradient(to right, rgba(255, 255, 255, .4), rgba(255, 255, 255, .4)) no-repeat bottom / 100% 50px,
url(https://www.nasa.gov/sites/default/files/20140824_0304_171.jpg) center / cover;
}
.photo-2 {
background:
linear-gradient(to right, rgba(255, 255, 255, .4), rgba(255, 255, 255, .4)) no-repeat bottom / 100% 50px,
url(https://alifebeyondrubies.files.wordpress.com/2013/03/walls01.jpg) center / cover;
}
.photo-3 {
background:
linear-gradient(to right, rgba(255, 255, 255, .4), rgba(255, 255, 255, .4)) no-repeat bottom / 100% 50px,
url(http://photos.epicurious.com/2015/01/12/54b4006b2413537c0d45738f_51143820_spaghetti-mussels-white-beans_6x4.jpg) center / cover;
}
<div class="photo photo-1"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
</div>
<div class="photo photo-2"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
</div>
<div class="photo photo-3"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
</div>
what about using text / box-shadow? You could apply a text-shadow with white or black, and or a box-shadow to your .tag class. This way
there will be enough contrast.
Another way would be, using the same Image as a background Image on
the tag, and applying filter to it. (hue-rotate or brightness etc.)
Something else that comes to my mind would be a calculation using
canvas, to detect whether the bottom corner is dark or light, and
adding another class to the .tag, so that you can use two versions.
One for each type of background
Lastly maybe blend-modes are an option: mix-blend-mode: difference;
Related
I've tried for several days to blend a colored background over a text with the same color and end up with the blended text to get white. Here is an example of what i managed to archive with only black and white:
But as soon as i change the color of the text and background from black to - for example - blue, the text does not get white but yellow or another color instead.
I used the CSS mix-blend-mode exclusion.
A working example with black and white can currently be found here. My goal is to replace the black and white primary button with a blue and white one.
If we consider the mix-blend-mode difference, this takes the difference between the background and the content colors.
So, if we have our text as blue which is rgb(0, 0, 255) to get to white we need to difference it with rgb(255, 255, 0).
Conversely, if our text is rgb(255, 255, 0) and we difference it with white which is rgb(255, 255, 255) we get rgb(0, 0, 255) which is blue.
So, we give the text a color of rgb(255, 255, 0) and ask it to blend with the background which is white and that will give us blue. Then as we overlay a blue we will get white text.
Here's the snippet. I haven't provided the wavyness which would be the subject of a different question.
UPDATE: as can be seen from the comments, the results so far on Windows10 and IOS look OK, but on MACOS variable results have been seen with the text taking on some pale color in Chrome and Safari, though being white on Firefox. Differences in interpretation (especially between mix-blend-mode and background-blend-mode) need further investigation.
body {
position: relative;
background-color: rgb(255, 255, 255);
width: 100vw;
height: 100vh;
}
#keyframes updown {
0% {
height: 0;
top: 200px;
}
50% {
height: 200px;
top: 0;
}
100% {
height: 0;
top: 200px;
}
}
.background {
position: absolute;
background-color: rgb(0, 0, 255);
width: 400px;
height: 200px;
animation: updown 10s ease infinite;
}
.text {
position: absolute;
font-family: sans-serif;
width: 400px;
color: rgb(255,255,0);/* complement of blue */
mix-blend-mode: difference;
text-align: center;
font-size: 50px;
}
<div class="background"></div>
<div class="text">Primary button</div>
I have a button that has a background color slide in from the right on hover, which works fine, however I need the text color to change as well. I have managed to have it fade, but that doesn't work properly. What I would like is a color transition slide in from the right in concert with the background change.
.slideybutton {
background-size: 200% 100%;
background-image: linear-gradient(to right, white 50%, blue 50%);
transition: background-position 1s linear, color 1s linear;
color: blue;
}
.slideybutton:hover {
background-position: -100% 0;
color: white;
}
<a class="slideybutton">
Lorem ipsum dolor sit amet.
</a>
I have seen this question, but the only solution is unfeasible in this instance.
Sliding in changing text color animation
Is there some CSS trick I am missing? Google searches don't result in anything pointing me in the right direction, so I am concerned I am attempting the impossible.
I'm happy to utilise JS or jQuery if it will accomplish what I want.
This could be done by "combining the text with the background", the key is property background-clip, check this out:
.slideybutton {
background-size: 200% 100%;
background-image: linear-gradient(to right, blue 50%, white 50%),
linear-gradient(to right, white 50%, blue 50%);
transition: background-position 1s linear;
-webkit-background-clip: text, border-box;
background-clip: text, border-box;
color: transparent;
}
.slideybutton:hover {
background-position: -100% 0;
}
<a class="slideybutton">
Lorem ipsum dolor sit amet.
</a>
Just providing an alternative using pseudo elements. Works fine on chrome.
.slideybutton {
position: relative;
}
.slideybutton:hover {
/* to fix a bug in IE */
}
.slideybutton:hover::after {
width: 100%;
}
.slideybutton::before {
content: attr(title);
color: blue;
}
.slideybutton::after {
content: attr(title);
position: absolute;
left: 0;
width: 0;
top: 0;
bottom: 0;
color: white;
transition: width 1s linear;
background-color: blue;
white-space: nowrap;
overflow: hidden;
}
<a class="slideybutton" title="Lorem ipsum dolor sit amet.">
</a>
i don't think you'll be able to do this elegantly using a pure css solution at the moment. backdrop filters look promising for what you want to achieve - you would slowly overlay an element with a backdrop filter - this would apply the filter to the text as you move across it.
Check out more here https://webkit.org/demos/backdrop-filter/
I'm honestly not sure where to begin on this one (I'm a graphic designer digging a bit deeper into HTML/CSS, but my current experience is rather slim, so this problem is beyond my ability at the moment):
In part of my newest site design I've broken up sections of the site with banded shades: sections alternate between having the standard page background and applying a 10% black transparency overlay, which serves to distinguish the next section.
The problem is that every new section is supposed to have a block of three centered arrows cut out of the darker (or lighter) shade above, like so:
I know how I could manage this with images, but since the background is a repeating pattern that solution doesn't really work.
Any advice/tips that could help me solve this problem? Basically, all light sections need to begin with three arrows of 10% black transparency, and all dark sections need to begin with three arrows cut out of the 10% transparency background.
Is there an HTML/CSS based way to do this?
Container with trapezoid top border
Trapezoid:
I add the desired border on the top with a pseudo-element ::before.
Choose to display this content as a block this way it gets the size of its container.
Positioned this element relative so it is not displayed inside its container. position:relative; & top: -30px;
The border got a static 30px, and that's why its displayed -30px higher so its exactly above our .cut-out.
Transparency:
Setting the color with rgba() lets you set the opacity of the color.
So rgba(0,0,0, 0.1) sets the container/trapezoid to have a opacity of 10%. where a last value of 1 would equal 100% opacity. (Where you would use rgb() instead)
body {
margin: 0;
}
main {
background-color: rgba(0, 0, 0, 0.1);
}
.cut-out {
display: inline-block;
float: left;
background-color: rgba(0, 0, 0, 0.1);
width: 100px;
height: 150px;
margin: 40px 0 0 0;
}
.cut-out::before {
content: "";
border-bottom: 30px solid rgba(0, 0, 0, 0.1);
border-left: 30px solid transparent;
border-right: 30px solid transparent;
display: block;
position: relative;
top: -30px;
}
.stop {
clear: both;
}
<main>
<div class="cut-out">Lorem ipsum dollar si amet, Lorem ipsum dollar si amet, </div><!--
--><div class="cut-out" style="width:150px;">Lorem ipsum dollar si amet, </div><!--
--><div class="cut-out" style="width:250px;"></div><!--
--><div class="cut-out"></div>
<div class="stop"></div>
</main>
Here's a fiddle that should help you out. This is done using simple CSS, and I'm just illustrating it here. You can adapt this to match your needs.
Sample HTML:
<div class="cutout"></div>
And the CSS
.cutout {
width: 100px;
height: 0px;
background: none;
border-bottom: solid 30px rgba(0, 0, 0, 0.1);
border-right: solid 30px transparent;
border-left: solid 30px transparent;
border-top: solid 0 transparent;
}
This will give you one of the elements to be repeated. To get some understanding of how this works, check out the following CSS in the updated fiddle:
.cutout {
width: 100px;
height: 100px;
background: rgba(0, 0, 0, 0.05);
border-bottom: solid 30px rgba(0, 255, 0, 0.1);
border-right: solid 30px rgba(0, 0, 0, 0.05);
border-left: solid 30px rgba(0, 0, 0, 0.05);
border-top: solid 0 rgba(0, 0, 0, 0.05);
}
Basically, we're assigning transparent color to the right and left borders, and giving the div a height of 0. This means only the bottom border remains visible, and a trapezoidal shape is formed because of the border width.
Edit: Looks like the links posted by #Myke showcase this already, I recommend playing around with code like this until you get a good idea of how to render similar shapes.
I'm trying to do something like this for a client who has a blog.
She wanted a semi transparent border. I know that's possible with making it just a background. But I can't seem to find the logic/code behind this kind of css technique for banners. Does anybody know how to do this? It would be a lot of help because that's the look my client's wanting to achieve for his blog....
Well if you want fully transparent than you can use
border: 5px solid transparent;
If you mean opaque/transparent, than you can use
border: 5px solid rgba(255, 255, 255, .5);
Here, a means alpha, which you can scale, 0-1.
Also some might suggest you to use opacity which does the same job as well, the only difference is it will result in child elements getting opaque too, yes, there are some work arounds but rgba seems better than using opacity.
For older browsers, always declare the background color using #(hex) just as a fall back, so that if old browsers doesn't recognize the rgba, they will apply the hex color to your element.
Demo
Demo 2 (With a background image for nested div)
Demo 3 (With an img tag instead of a background-image)
body {
background: url(http://www.desktopas.com/files/2013/06/Images-1920x1200.jpg);
}
div.wrap {
border: 5px solid #fff; /* Fall back, not used in fiddle */
border: 5px solid rgba(255, 255, 255, .5);
height: 400px;
width: 400px;
margin: 50px;
border-radius: 50%;
}
div.inner {
background: #fff; /* Fall back, not used in fiddle */
background: rgba(255, 255, 255, .5);
height: 380px;
width: 380px;
border-radius: 50%;
margin: auto; /* Horizontal Center */
margin-top: 10px; /* Vertical Center ... Yea I know, that's
manually calculated*/
}
Note (For Demo 3): Image will be scaled according to the height and
width provided so make sure it doesn't break the scaling ratio.
You can also use border-style: double with background-clip: padding-box, without the use of any extra (pseudo-)elements. It's probably the most compact solution, but not as flexible as the others.
For example:
<div class="circle">Some text goes here...</div>
.circle{
width: 100px;
height: 100px;
padding: 50px;
border-radius: 200px;
border: double 15px rgba(255,255,255,0.7);
background: rgba(255,255,255,0.7);
background-clip: padding-box;
}
If you look closely you can see that the edge between the border and the background is not perfect. This seems to be an issue in current browsers. But it's not that noticeable when the border is small.
Using the :before pseudo-element,
CSS3's border-radius,
and some transparency is quite easy:
LIVE DEMO
<div class="circle"></div>
CSS:
.circle, .circle:before{
position:absolute;
border-radius:150px;
}
.circle{
width:200px;
height:200px;
z-index:0;
margin:11%;
padding:40px;
background: hsla(0, 100%, 100%, 0.6);
}
.circle:before{
content:'';
display:block;
z-index:-1;
width:200px;
height:200px;
padding:44px;
border: 6px solid hsla(0, 100%, 100%, 0.6);
/* 4px more padding + 6px border = 10 so... */
top:-10px;
left:-10px;
}
The :before attaches to our .circle another element which you only need to make (ok, block, absolute, etc...) transparent and play with the border opacity.
use rgba (rgb with alpha transparency):
border: 10px solid rgba(0,0,0,0.5); // 0.5 means 50% of opacity
The alpha transparency variate between 0 (0% opacity = 100% transparent) and 1 (100 opacity = 0% transparent)
This question already has answers here:
How do I reduce the opacity of an element's background using CSS?
(29 answers)
Closed yesterday.
I want to make the list menu's background disappear by using opacity, without affecting the font. Is it possible with CSS3?
now you can use rgba in CSS properties like this:
.class {
background: rgba(0,0,0,0.5);
}
0.5 is the transparency, change the values according to your design.
Live demo http://jsfiddle.net/EeAaB/
more info http://css-tricks.com/rgba-browser-support/
Keep these three options in mind (you want #3):
1) Whole element is transparent:
visibility: hidden;
2) Whole element is somewhat transparent:
opacity: 0.0 - 1.0;
3) Just the background of the element is transparent:
background-color: transparent;
To achieve it, you have to modify the background-color of the element.
Ways to create a (semi-) transparent color:
The CSS color name transparent creates a completely transparent color.
Usage:
.transparent{
background-color: transparent;
}
Using rgba or hsla color functions, that allow you to add the alpha channel (opacity) to the rgb and hsl functions. Their alpha values range from 0 - 1.
Usage:
.semi-transparent-yellow{
background-color: rgba(255, 255, 0, 0.5);
}
.transparent{
background-color: hsla(0, 0%, 0%, 0);
}
As of the CSS Color Module Level 4, rgb and hsl works the same way as rgba and hsla does, accepting an optional alpha value. So now you can do this:
.semi-transparent-yellow{
background-color: rgb(255, 255, 0, 0.5);
}
.transparent{
background-color: hsl(0, 0%, 0%, 0);
}
The same update to the standard (Color Module Level 4) also brought in support for space-separated values:
.semi-transparent-yellow{
background-color: rgba(255 255 0 / 0.5);
}
.transparent{
background-color: hsla(0 0% 0% / 0);
}
I'm not sure why would these two be any better than the old syntax, so consider using the a-suffixed, comma-separated variants for greater support.
Besides the already mentioned solutions, you can also use the HEX format with alpha value (#RRGGBBAA or #RGBA notation).
That's contained by the same CSS Color Module Level 4, so it has worse support than the first two solutions, but it's already implemented in larger browsers (sorry, no IE).
This differs from the other solutions, as this treats the alpha channel (opacity) as a hexadecimal value as well, making it range from 0 - 255 (FF).
Usage:
.semi-transparent-yellow{
background-color: #FFFF0080;
}
.transparent{
background-color: #0000;
}
You can try them out as well:
transparent:
div {
position: absolute;
top: 50px;
left: 100px;
height: 100px;
width: 200px;
text-align: center;
line-height: 100px;
border: 1px dashed grey;
background-color: transparent;
}
<img src="https://via.placeholder.com/200x100">
<div>
Using `transparent`
</div>
hsla():
div {
position: absolute;
top: 50px;
left: 100px;
height: 100px;
width: 200px;
text-align: center;
line-height: 100px;
border: 1px dashed grey;
background-color: hsla(250, 100%, 50%, 0.3);
}
<img src="https://via.placeholder.com/200x100">
<div>
Using `hsla()`
</div>
rgb():
div {
position: absolute;
top: 50px;
left: 100px;
height: 100px;
width: 200px;
text-align: center;
line-height: 100px;
border: 1px dashed grey;
background-color: rgb(0, 255, 0, 0.3);
}
<img src="https://via.placeholder.com/200x100">
<div>
Using `rgb()`
</div>
hsla() with space-separated values:
div {
position: absolute;
top: 50px;
left: 100px;
height: 100px;
width: 200px;
text-align: center;
line-height: 100px;
border: 1px dashed grey;
background-color: hsla(70 100% 50% / 0.3);
}
<img src="https://via.placeholder.com/200x100">
<div>
Using `hsla()` with spaces
</div>
#RRGGBBAA:
div {
position: absolute;
top: 50px;
left: 100px;
height: 100px;
width: 200px;
text-align: center;
line-height: 100px;
border: 1px dashed grey;
background-color: #FF000060
}
<img src="https://via.placeholder.com/200x100">
<div>
Using `#RRGGBBAA`
</div>
yes, thats possible. just use the rgba-syntax for your background-color.
.menue {
background-color: rgba(255, 0, 0, 0.5); //semi-transparent red
}
Here is an example class using CSS named colors:
.semi-transparent {
background: yellow;
opacity: 0.25;
}
This adds a background that is 25% opaque (colored) and 75% transparent.
CAVEAT
Unfortunately, opacity will affect then entire element it's attached to.
So if you have text in that element, it will set the text to 25% opacity too. :-(
The way to get past this is to use the rgba or hsla methods to indicate transparency* as part of your desired background "color". This allows you to specify the background transparency*, independent from the transparency of the other items in your element.
Technically we're setting the opacity, though we often like to speak/think in terms of transparency. Obviously they are related, inverses of each other, so setting one decides the other.
The number specified is the opacity %. 1 is 100% opaque, 0% transparent & vice versa).
Here are 3 ways to set a blue background at 75% opacity (25% transparent), without affecting other elements:
background: rgba(0%, 0%, 100%, 0.75)
background: rgba(0, 0, 255, 0.75)
background: hsla(240, 100%, 50%, 0.75)
In this case background-color:rgba(0,0,0,0.5); is the best way.
For example: background-color:rgba(0,0,0,opacity option);
Try this:
opacity:0;
For IE8 and earlier
filter:Alpha(opacity=0);
Opacity Demo from W3Schools
Yes you can just plain text as
.someDive{
background:transparent
}
For your case, we can use rgba():
First, we manipulate the background-color, and use rgba.
.selector {
background-color: rgba(0, 0, 0, 0.3);
}
Now what this does is, it basically adds an opacity to your element, along with the black background color. This is how it'd look when you run it.
body {background-color: #0008f3;}
.container {
height: 100px;
width: 100px;
background-color: rgba(255,255,255,0.5);
}
<body>
<div class="container"></div>
</body>
full transparent -> .youClass{background: rgba(0,0,0,0.001);}