Inherit color but override opacity/transparency - html

Is it possible to inherit the color but override the opacity value? Here's an example in pseudo CSS:
.color-class {
background-color: rgba(255, 0, 0, 0);
}
.lighten {
background-color: rgba(inherit, inherit, inherit, .4);
}
Applied to
<div style="color-class">I am red</div>
<div style="color-class lighten">
I am red and a little bit transparent
</div>
should result in a colored element and the other one being the same (inherited) color but with added transparency.
I basically want to have a CSS class that lightens (or darkens) the background color without changing the color value.

A solution is to use pseudo element as background and simply control its opacity :
div {
padding: 40px;
}
.color-class {
position: relative;
}
.color-class:before {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgb(255, 0, 0);
opacity: 1;
z-index:-1;
}
.lighten:before {
opacity: 0.5;
}
<div class="color-class">I am red</div>
<div class="color-class lighten">
I am red and a little bit transparent
</div>

Firstly, this would not work because inherit takes the value from an elements parent element not its sibling element. See: https://developer.mozilla.org/en-US/docs/Web/CSS/inherit
Secondly, the inherit keyword is a property-value. It cannot be used as an argument to a browser function (rgba) as the function itself is a property-value.
You also don't need to try this hard to enforce inheritance and re-usability, it will often bloat your code and make it over-engineered.
You would ideally have a set colour scheme and therefore be able to choose a fixed colour for lighten, considering you would be re-using this there isn't that much need to try and make it dynamic like that.
Other options you can go for if you REALLY want this functionality are using SASS/SCSS mix-ins to mimic this inheritance, JavaScript could also be an alternative however for what you're trying to achieve this would be really in-efficient.

You can do it, just use CSS variables. Let's say you have element with set background and you want to change its opacity.
<div class="bg-yellow">Yellow div</div>
Add new class for changing opacity:
<div class="bg-yellow bg-opacity-20">Yellow div</div>
And in your CSS:
.bg-yellow {
--bg-opacity: 1;
background-color: rgba(255,230,0, var(--bs-opacity));
}
.bg-opacity {
--bg-opacity: 0.2;
}
"255,230,0" is yellow btw...
And that's it, you can also manipulate this method as you want according to your needs.
.bg-yellow {
--bg-opacity: 1;
background-color: rgba(255,230,0,var(--bg-opacity));
}
.bg-opacity-20 {
--bg-opacity: 0.2;
}
<div class="bg-yellow bg-opacity-20">Yellow div</div>

Related

Css overlay with background color inherited from theme

I'm trying to put an overlay on my page that will cover all the content.
The problem is that my site allows you to change the theme colors, and the overlay div does not inherit the color from the theme.
The only way to change it is using background-color: rgba( x, y, z, 1.0)
Here is my css for the overlay
.bio-overlay {
position: fixed; /* Sit on top of the page content */
display: block;
width: 100%; /* Full width (cover the whole page) */
height: 100%; /* Full height (cover the whole page) */
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 2048;
cursor: pointer; /* Add a pointer on hover */}
Is there a way to do this with css? If not I'll settle for some clever javascript. Thanks
In theory, if the theme is class-based, you can steal, or even make another class that only has a background color attached to it, and apply it to the overlay as well. This would make it so if the theme changed, the overlay color would change.
.backgroundColor {
background-color: rgba(x, y, z, 1.0);
}
<div class="bio-overlay backgroundColor">
Content
</div>
Another solution is, if the overlay is a child of the theme, you can select the overlay and apply a background color to it that way.
.themeClass .bio-overlay {
background-color: rgba(x, y, z, 1.0);
}
This will basically overload the .bio-overlay class and if the themeClass is a parent, it'll also apply the background color.
EDIT
To answer your comment, yes. In the stylesheet YOU edit, do something like this...
.whatevertheme .bio-overlay {
background-color: _whatever_;
}
.whatevertheme2 .bio-overlay {
background-color: _whatever2_;
}
....
It doesn't matter what file the style is in, all that matters is that it is included in the page. As I said in the comment, the only real downside is you'll break theme separation.

Opacity on background image

As far as I know I can't directly change the opacity of a background image but using ::before and ::after doesn't seem to let my image show up. Am I doing it wrong?
HTML
flower window boxes
All of our products come in virtually any length up to 16 feet and two sizes. Our standard size boxes are designed to accommodate almost any flower. Our XL sizes are taller and deeper to provide more root space for plants making them the ideal sized window boxes for plants.
</div>
<div class="card-back">
<h2 class="click-here"><b>Visit Site</b></h2>
<div class="info">
<h2 class="info">Email:</h2>
<h2 class="info">Phone:</h2>
</div>
</div>
<!-- Content -->
<div class="all-content">
<h1>Contrary to popular belief</h1>
</div>
</li>
Current CSS
.content li:nth-child(1) .card-back{
background-image:url(../images/sponsor-imgs/Cellular%20PVC%20Columns-Kingston-1.jpg);
width: 100%;}
What I've tried
.backimg::after {
background-image:url(../images/backimg/wide.png);
opacity: 0.5;
}
.backimg::before{
background-image:url(../images/backimg/wide.png);
opacity: 0.5;
}
div::after {
opacity: 0.5;
}
On a side not i know i can simply make the images themselves transparent, but i feel like a code to do it much more useful in the long run. thanks in advance.
::before and ::after require a content property. You can set it to an empty string but it must be included.
In most cases you also need to define a display property and assign some dimensions to the element (unless you are using something like position: absolute; top: 0; bottom: 0; left: 0; right: 0; - in which case, you don't).
.backimg {
background: red;
}
.backimg::after {
content: "";
display: block;
width: 200px;
height: 200px;
background-image: url(http://placehold.it/200x200);
opacity: 0.5;
}
<div class="backimg"></div>
You are missing the .backimg class in your html.
Dont use double :: and add content and display properties to after. Also some dimensions wouldnt hourt (width,height)
.class:after{
Cintent:"";
Display:block; // change as you see fit
}

CSS: Prevent parent element getting :active pseudoclass when child element is clicked

JSFiddle
When you click the button, you see that :active pseudoclass is triggered for the parent div. Is there a pure CSS (or some JS library) way of :active pseudoclass not toggling on button click?
I tried z-index, position: absolute & fixed and no success.
From the spec:
Selectors doesn't define if the parent of an element that is ‘:active’ or ‘:hover’ is also in that state.
That means it's implementation dependent. If an implementation chose to act this way (as current browsers obviously do), there's nothing in the standard that can change that.
With CSS4, you might be able to do:
.parent:active:not(:has(:active)) {
color: red;
}
but that is neither available nor finalized yet.
If you really want to solve this with CSS only:
If your button is active, add a :before-pseudo-element and with position: absolute; give the :before the same background as the parents.
button:active::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #eee;
z-index: -1;
}
Now all that is needed is that the parent is :
position: relative;
z-index: 0;
Have a look: http://jsfiddle.net/s0at4w4b/4/
This does not solve the underlying issue, but is a solution for your current problem.
I don't think :has pseudo-class will ever be available in stylesheets. If browsers finally decide to implement it, it will probably be only for JS APIs like querySelector.
However, I have much more hopes for :focus-within, which seems much simpler to implement.
#parent:active:not(:focus-within) {
background-color: red;
}
Of course, it will only prevent :active from being applied to #parent when clicking a focusable element like a button. You can make other elements focusable by adding tabindex = "-1"
Sadly, :focus-within is not widely supported, but you can use a JS polyfill.
#parent {
border: 1px solid black;
width: 300px;
height: 300px;
}
#parent:active:not(.focus-within) {
background-color: red;
}
<script src="https://gist.githubusercontent.com/aFarkas/a7e0d85450f323d5e164/raw/"></script>
<div id="parent">
<button>Click me</button>
<p tabindex="-1">Or me</p>
</div>
Github does not allow hotlinking, so the snippet above might not work unless you copy the polyfill to your server and use it.
Perhaps the simplest way of achieving what you probably really want to do is to put not put the button inside the div you don't want activated.
Here, you have a container div, which contains a background div (the equivalent of the parent div in your original example). The background div has an active state separate from the button's.
.container {
position: relative;
width: 200px;
height: 200px;
}
.background {
position: absolute;
width: 100%;
height: 100%;
border: 1px solid black;
background-color: #eee;
}
.background:active {
background-color: red;
}
button {
position: relative;
}
<div class="container">
<div class="background"></div>
<button>Click me!</button>
</div>
This may or may not work for you, but this is how I achieve it with pure CSS. The only caveat is the dependence of focus-within which isn't supported by IE or Edge.
.parent {
transition: background-color;
}
.parent:active:not(:focus-within) {
background-color: red;
transition-delay: 1ms; // Delay one cycle to allow child to focus
}
What's going on here is, the parent element will get the active state, as will the child that gets clicked. The only difference is that the focus will apply to the child element, but only on the next cycle. To circumvent any animations from while in this 2 step process, apply a 1ms delay. The next cycle, the element will be active, but the focus will be applied to the child. Thus, the parent will not apply the transition. I would imagine animation delay: 1ms would work the same way.
Another alternative is to give the item a tabindex=-1 attribute and use
.parent {
transition: background-color;
}
.parent:active:focus {
background-color: red;
}
The only issue with this is the fact it may change keyboard navigation behavior and relies on some HTML as well. If you do want keyboard navigation use tabindex=0 or any value besides -1. But there's no JS used.
There are some nice polyfills for focus-within that you can use for IE/Edge but that would go outside "CSS Only".
But, we can put both of them together to create this:
.parent {
transition: background-color;
}
.parent[tabindex]:active:focus {
background-color: red;
}
.parent:active:not(:focus):not(:focus-within) {
background-color: red;
transition-delay: 1ms;
}
This works on IE11, Edge, and Chrome.
http://jsfiddle.net/s0at4w4b/42/
here's a jquery solution instead of using the css pseudo class :active
$(document).ready(function() {
$('button').mousedown(function(e){
e.stopPropagation();
console.log('i got clicked');
});
$('div').mousedown(function(e){
$('div').css('background', 'red')
}).mouseup(function(e){
$('div').css('background', '#eee')
});
$(document).mouseup(function(e){
$('div').css('background', '#eee')
});
});
div {
width: 200px;
height: 200px;
background-color: #eee;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<button>Qlick me</button>
</div>
As far as I know, the the active state will bubble up. So all parent nodes will have an active state.
Therefore, I don't now of a pure CSS solution. You can avoid a javascript solution (which I assume is what you're really after), by altering the markup so that the div that has an active state is no longer a parent of the button. You can make them siblings, for example.
The CSS part of that solution is then fixing the layout so it appears the same now that they are sibilings as what it did when they were parent>child.
Without seeing a fiddle of what you're working with, I can't offer you a more specific solution I'm afraid.
try this
html:
<div class="current" id="current">
<button id="btnclick" >Qlick me</button>
</div>
css script:
div {
width: 200px;
height: 200px;
background-color: #eee;
border: 1px solid black;
}
.current_active{
background-color: red;
}
jquery:
$("#btnclick").click(function(){
$("#current").toggleClass("current_active");
});
JSFiddle
ps: include the jquery library file
The :active pseudo-class applies while an element is being activated by the user. For example, between the times the user presses the mouse button and releases it. On systems with more than one mouse button, :active applies only to the primary or primary activation button (typically the "left" mouse button), and any aliases thereof.
There may be document language or implementation specific limits on which elements can become :active. For example, [HTML5] defines a list of activatable elements.
The parent of an element that matches :active also matches :active.
So there,s no way
Instead of div:active {...} you should code div:active:not(:hover) {...} and the background-color stays untouched.
(old snippet removed)
UPDATE
To keep the main div behaviour intact and a more generic approach I usually create several layers.
Check the snippet below, toggling to green is just to prove that it works while position and abolute are just quick and dirty for now:
#layer-data {
width: 200px;
height: 200px;
background-color: #eee;
border: 1px solid black;
}
#layer-data:active {
background-color: red
}
#layer-btns:active {
background-color: green
}
#layer-btns {
z-index: 1;
position: absolute;
top: 1px;
left: 1px;
background: transparent;
padding: 5px;
width: auto;
height: auto
}
#layer-data {
z-index: 0;
position: absolute;
top: 0;
left: 0;
text-align: center;
line-height: 200px
}
<div id="layer-btns">
<button>Qlick me</button>
<br/>
<button>Qlick me too</button>
<br/>
<button>Qlick me three</button>
</div>
<div id="layer-data">
some data-layer
</div>
There doesn't seem to any CSS way to handle this case. (not sure about CSS4, the way Amit has suggested.) So here is JQuery way.
The idea is you handle mousedown and mouseup events at 3 levels:
the parent div
the button where you don't want the active state propagated to parent div (".btn1" in the example below)
any other children except the button in second condition. (".btn2" in the example below)
JS Fiddle
HTML:
<div>
<button class="btn1">Qlick me1</button>
<button class="btn2">Qlick me2</button>
</div>
JQuery:
$(function(){
$('div').each(function(e){
$(this).mousedown(function(e){
$(this).addClass("activeClass");
}).mouseup(function(e){
$(this).removeClass("activeClass");
});
});
$('div .btn1').each(function(e){
$(this).mousedown(function(e){
e.stopPropagation();
}).mouseup(function(e){
e.stopPropagation();
});
});
$('div :not(.btn1)').each(function(e){
$(this).mousedown(function(e){
$(this).parent().addClass("activeClass");
}).mouseup(function(e){
$(this).parent().removeClass("activeClass");
});
});
});
CSS:
div {
width: 200px;
height: 200px;
background-color: #eee;
border: 1px solid black;
}
.activeClass {
background-color: red;
}
CSS pseudo-elements are incredibly useful -- they allow us to create CSS triangles for tooltips and perform a number of other simple tasks while preventing the need for additional HTML elements. To this point, these pseudo-element CSS properties have been unreachable by JavaScript but now there's a method for getting them!
Check this:
http://davidwalsh.name/pseudo-element
http://davidwalsh.name/ways-css-javascript-interact

How to highlight a div with children (with partial opacity layer?) Like Yahoo mail, see pic

In Yahoo mail, when you are writing an email and you drag a file onto the page and hover, the message area becomes highlighted. It can be seen here:
The part of this that I don't get is how to have the blue area appear with partial opacity over the things under it that are normally visible.
With:
#blueBox {
background-color: #FFD090;
opacity: 0.0;
}
If the msgContent is a child of blueBox:
<div id='msgBox'>
<div id='blueBox'>
<div id='msgContent'>
... all the message contents, buttons, etc.
</div>
</div>
</div>
and when msgBox is hovered I increase blueBox opacity from 0 to say 0.6, the blueBox will show but the msgContent div is hidden until the hover event. It should be visible always.
If the msgContent div is not a child of blueBox, then the blueBox doesn't cover it.
I've tried rgba (http://jsfiddle.net/mkasson/nJcxQ/19/) like here on SO, but it doesn't cover over the child elements.
Couldn't do my usual watching/inspecting via browser's webdev tools because focus was never on the browser while dragging the file onto it.
Thanks!
Here is how I would go about this,
(What the problem is, you are using the parents background. You can't make the parents background go over it's content, that is not what a background does. It merely sites behind everything it is containing and acts as a background.)
html,
<div class="messageContent">
<span class="overlay"></span>
<p>Darn fanatically far and tarantula jeepers meek a secret much so hence underneath monogamously interwove apart gosh spilled far where and badger.</p>
This is a link
</div>
css,
.messageContent {
color: #000;
position: relative;
height: 100%;
width: 100%;
}
.overlay {
position: absolute;
top: 0;
left: 0;
background: lightBlue;
opacity: 0;
height: 100%;
width: 100%;
display: block;
z-index: 100;
}
.messageContent:hover .overlay {
opacity: 0.6;
}
What I am doing is placing an absolute span tag inside of the parent to act as the color overlay. When the parent is hovered the overlay child will become active by increasing it's opacity.
JSFIDDLE
Here's how I would do it.
<div id='msgBox'>
<div id='blueBox'>
</div>
<div id='msgContent'>
... all the message contents, buttons, etc.
</div>
</div>
CSS
#blueBox {
background-color: #FFD090;
opacity: 0.0;
position: absolute;
top: 0;
left: 0;
}
jQuery
$("#msgBox").hover(function(){
$("#blueBox").css({top:$(this).css("top")}).height($(this).outerHeight()).width($(this).outerWidth()).animate({opacity:0.6});
},function(){
$("#blueBox").animate({opacity:0}).height(0).width(0);
});
http://jsfiddle.net/54cx7/2/
The problem is that since content is a child of bluebox, then it inherits the 0 opacity.

Is it possible to show a div on click using the :active selector in CSS?

I'm looking to show a div on click. The goal is to use pure CSS only, no jQuery.
Working FIDDLE Demo
Consider that you want something like this:
We write our markup as simple as possible. One element for container, one element for our link and one another element for popup:
<!-- [container] -->
<div class="link-with-popup">
<!-- link -->
<div class="link">CSS</div>
<!-- [popup] -->
<div class="popup">
<div class="box">CSS Description</div>
</div>
<!-- [/popup] -->
</div>
<!-- [/container] -->
Here is our layer structure in picture:
CONTAINER
Let's write CSS for our container.
.link-with-popup {
/* for visualizing */
background: yellow;
/* we need relative, because childs are absolute */
position: relative;
margin-bottom: 10px;
height: 30px;
width: 400px;
}
[!] Note that we make our container relative. Because the children will be in absolute mode.
LINK
We create our link as an absolute element from left, just as shown in the figure above.
.link {
background: blue;
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 100px;
z-index: 10;
}
POPUP
The dimention of popup element is same as the container, so we set all top, left, right, bottom properties to 0.
.popup {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: green;
z-index: 20;
}
[!] Note that z-index of popup element must be greater than link element.
.popup {
/* we won't show the popup yet */
display: none;
}
By now, we'll get this result (check it on jsFiddle):
Now we want the click for our link. This must be done with :active pseudo selector in CSS. But how we must show the poup? We have to get the next sibling element by the link. We use the + selector in CSS:
.link:active + .popup {
display: block;
}
See the result on jsFiddle. But the problem is that when user realize the mouse, the popup will disappear (as it display is set to none).
So we set the :hover rule for the popup and make it block.
.popup:hover {
display: block;
}
Check the jsFiddle demo. Now we get close enough. The only issue that the popup element, hide our link.
But it doesn't matter, because we won't set background for our popup (it will be transparent).
TEXT
For wanted text in popup element, we set this rules:
.popup .box {
position: absolute;
/* note that we make a gap from left to don't hide the link */
left: 130px;
top: 0;
right: 0;
bottom: 0;
background: #505050;
}
Check the jsFiddle demo. Now we have all things that we need.
Now it's time to make our popup element transparent (by setting the background as transparent or simply remove the background: green; rule):
.popup {
background: transparent;
}
And here is the final jsFiddle result. And if you add some extra CSS to it, it can be more stylish. Something like this that I've created.
Some important note to memorize:
In the final result, there is a gap between the link (blue one) and the popup (gray one). But the fact is that the gray element is not our popup. It's a child of popup and our popup is an 100% width and height element on the container.
Working FIDDLE Demo
Another way is to use the :target property (only works in moderns browsers).
Here's a qucik DEMO where I've hidden the div by applying opacity: 0; and the when you click the link the div changes to opacity: 1; The link and the div are matched using a hash in the url.
Here's the code from my example.
HTML
Click me
<br />
<div id="pop"></div>
CSS
#pop {
width: 100px;
height: 100px;
background: #000;
opacity: 0;
}
#pop:target {
opacity: 1;
}
There are some side effects though. The browser will jump/scroll down (not sure if it's possible to prevent this?) to the matched div and since we are using a hash in the url it will effect the browser history and, as mentioned above, it only works in modern browsers.
EDIT If you want to look into other hack/tricks for pure CSS click events, this is a good post - http://tympanus.net/codrops/2012/12/17/css-click-events/