I was experimenting around with box-shadows and thought it would be possible to make a window effect (as in the example below) so that you can hide text or an image underneath that can only be seen - or "opened" - when you hover/click.
Unfortunately it doesn't work like that, because the shadow will always be below the text or image, which I didn't realize until I was done.
Is there a fix for this, or should I use another way to get the same result without box-shadows?
body {
background: #20262E;
}
.window {
display: inline-block;
height: 200px;
width: 300px;
margin: 20px;
background: #F8F8F8;
text-align: center;
line-height: 200px;
}
.window {
box-shadow: inset 0 200px #0084FF;
transition: box-shadow 1s ease-in-out;
}
.window:hover {
box-shadow: inset 0 0 #0084FF;
}
<div class="window">
box 1
</div>
*Note: I haven't been able to figure out why the transition is flickering :/
Agree that it's probably a bug with box-shadow. If you're looking for another CSS way to handle this, how about the :before or :after pseudo elements?
body {
background: #20262E;
}
.window {
display: inline-block;
height: 200px;
width: 300px;
margin: 20px;
background: #F8F8F8;
text-align: center;
line-height: 200px;
position: relative;
}
.window:after {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: #0084FF;
transition: bottom 1s ease-in-out;
}
.window:hover:after {
bottom: 100%;
}
<div class="window">box 1</div>
Related
I know there is variety of JS libs for custom scroll but I believe with modern browsers it's better to go with native behaviour as more consistent and predictable. I assume I will have nice scrollbars in Chrome/Edge(Blink), acceptable in FF with their own simple color/sizing customisations and I won't care about other browsers.
The only problem I'm facing now is - I want li elements to go under the scrollbar. I tried to move content under it via transform: translateX(15px) / margin-right: -15px / right: -15px / overflow: overlay and nothing helped (while overflow:overlay does the job for <body/> it doesn't help with inner containers).
Any trick to achieve desired behaviour without JS?
*::-webkit-scrollbar-track {
background-color: transparent;
}
*::-webkit-scrollbar {
background-color: transparent;
transition: .3s;
}
*:hover::-webkit-scrollbar {
width: 15px !important;
}
*::-webkit-scrollbar-thumb {
border-radius: 10px;
border: 2px solid #444;
}
ul {
margin: 0;
padding: 0;
height: 100vh;
width: 70vw;
overflow-y: scroll;
background: linear-gradient(to top, #c6ffdd, #fbd786, #f7797d);
}
li {
cursor: pointer;
height: 40px;
transition: background .2s;
display: block;
}
li:hover {
background: rgba(255, 255, 255, 0.4);
}
ul:after {
content: "Scroll ↧";
color: white;
letter-spacing: 10px;
position: fixed;
left: 50%;
top: 50%;
font-size: 40px;
line-height: 1;
transform: translateX(-50%) translateY(-50%);
mix-blend-mode: difference;
}
body {
background: #12c2e9;
background: #c471ed20;
background: #444;
justify-content: center;
display: flex;
padding: 0;
margin: 0;
}
<ul>
<li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</ul>
The overflow: overlay does what you want. But take in account that this feature is not a standard. Also Edge will have another property -ms-overflow-style: -ms-autohiding-scrollbar; to hide scrollbar. Also test carefully in Firefox.
The overflow prop should be put on the body element, so scrollbar overlay on the top of ul.
body {
padding: 0;
margin: 0;
overflow: overlay;
}
ul {
margin: 0;
padding: 0;
background: linear-gradient(to top, #c6ffdd, #fbd786, #f7797d);
}
Working sample (tested in Chrome)
Goal: Make nice effect of hovering buttons in pure CSS, which will use ::after and ::before pseudo-elements. Look at this jsFiddle example to see, what I want to reach.
Code: Button will have some styling, also an background-color, which is turned off in this example.
.button {
display: inline-block;
position: relative;
height: 35px;
line-height: 35px;
padding: 0 15px;
/*background-color: white;*/
text-decoration: none;
color: black;
}
Problem: I want to use background-color and when I enable it, then I can't see pseudo-elements. It is like that, because these pseudo-elements have z-index: -1;, which put them behind the background. When I change z-index to 0 or 1, then text is not visible.
What I can't do: I can't add new elements inside buttons (like spans), because this is one already running website and client decided to change the behavior of buttons, so here I am. There are tons of buttons in this website, so this is the reason, why I want to find solution with pseudo-elements, because trying to find every single button and change them would be inappropriate.
If i understood you well, this is what you are looking for:
.button {
display: inline-block;
position: relative;
height: 35px;
line-height: 35px;
padding: 0 15px;
/*background-color: white;*/
text-decoration: none;
color: black;
border:1px solid;
}
a.button:before {
content: " ";
display: block;
z-index: -1;
position: absolute;
height: 0%;
top: 0;
right: 0;
left: 0;
background: #ddd;
transition: height 0.2s ease;
}
a.button:hover:before {
height:100%;
}
TEST
Consider an alternative method of doing the background colour transition thing.
As seen in this edited demo:
/* remove all references to .button::before */
.button {
background-image: linear-gradient(to bottom,
transparent, transparent 100%,
red 100%, red);
transition: background-image 0.5s ease 0s;
}
/* the "gradient" above has the practical result of being fully transparent,
but it has been carefully crafted so that the transition gives the desired result */
.button:hover {
background-image: linear-gradient(to bottom,
transparent, transparent 0%,
red 0%, red);
}
You can transition gadients, and in this case it is done stop-by-stop. The first and last stops don't change, but the middle two transition from 100% to 0%, essentially meaning that the cut-off point between transparent and red slides from the bottom to the top of the button, giving the effect you want.
You can now replace transparent with your desired background colour.
* You may need to remove the z-index:-1 from the ::after element to get the border effect back.
You can do something like,
HTML
CSS
body {
background: #FF7272;
}
.button {
display: inline-block;
position: relative;
height: 35px;
line-height: 35px;
padding: 0 15px;
text-decoration: none;
color: black;
z-index: 0;
background-color: white;
width: 50px;
}
.button::before, .button::after {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 0;
}
.button::after {
content: "TEST";
height: 50%;
width: 72px;
text-align: center;
z-index: 2;
line-height: 0.2;
border-left: 4px solid red;
border-right: 4px solid red;
border-bottom: 4px solid red;
}
.button::before {
height: 0%;
background-color: red;
transition: all 0.5s ease 0s;
z-index: 1;
}
.button:hover::before {
height: 100%;
}
Example: https://jsfiddle.net/LL0f7rwp/6/
Some values are hard coded, but hope you can get an idea out of it :)
It's because z-index: -1 and background-color: white will push your :before and :after elements beneath.
Remove z-index: -1 from :after and :before and add to hover .button:hover::before
Make the background-color: transparent while hovering. Updated fiddle.
body {
background: #FF7272;
}
.button {
display: inline-block;
position: relative;
height: 35px;
line-height: 35px;
padding: 0 15px;
background-color: white;
text-decoration: none;
color: black;
}
.button::before,
.button::after {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 0;
}
.button::after {
height: 50%;
border: 4px solid red;
border-top: 0;
}
.button::before {
height: 0%;
background-color: red;
transition: all 0.5s ease 0s;
}
.button:hover::before {
height: 100%;
z-index: -1;
}
.button:hover {
background-color: transparent;
}
TEST
I have a button with a background color, and text color set. What I like to do, is when the user hover the mouse on the button, the background to animate from bottom to top and change the color of the text to the color of the background.
For terms of simplicity of the code, I didn't put the transient I like to apply on the CSS properties. I know it's much easyer to change the button background code, but I plan to use transient for changing the :before height on hover.
So I have the following code, but when I hover the mouse on the button, the :before overlapping my button text.
I have also try to play with the z-index but no luck. Do you think is there any solution to this problem ?
body {
background: #111;
}
.btn {
color: #FFF;
background: #333;
border: none;
font-size: 18px;
font-weight: bold;
padding: 18px 60px;
position: relative;
}
.btn:before {
display: block;
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 0;
background: #FFF;
}
.btn:hover {
color: #333;
}
.btn:hover:before {
height: 100%;
}
<br />
Do Stuff
You need to add additional <span> element which would stay above the ::before pseudoelement:
span {
position: relative;
z-index: 1;
}
fiddle
The effect you desire can also be achieved without adding the additional span. By utilising the before and after pseudo elements for background colours and positioning them correctly.
To position the pseudo elements behind the text, set a positive z-index on the element and a negative z-index on the pseudo-element.
.btn {z-index: 1}
.btn:before {z-index: -1;}
Reference this article by Nicolas Gallagher which explains in more detail, see section 'Pseudo background-position' http://nicolasgallagher.com/an-introduction-to-css-pseudo-element-hacks/.
Also see fiddle with it in action: https://jsfiddle.net/j9whmcmz/2/
This technique does not work if you apply a background color to the .btn itself.
Choose your poison I guess, both solutions do the trick.
Try this:
body {
background: #333;
}
.btn {
color: #FFF;
background: #333;
display: inline-block;
position: relative;
overflow: hidden;
-webkit-transition: color 0.3s ease-in-out;
transition: color 0.3s ease-in-out;
}
.btn span {
display: inline-block;
padding: 18px 60px;
border: none;
font-size: 18px;
font-weight: bold;
z-index: 10;
position: relative;
}
.btn:after {
display: block;
content: '';
position: absolute;
top: 100%;
left: 0;
width: 100%;
max-height: 0;
background: #FFF;
height: 100%;
z-index: 9;
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
}
.btn:hover {
color: #333;
}
.btn:hover:after {
max-height: 100%;
top: 0;
}
<span>Do Stuff</span>
Solution if pretty obvious - content of the button should be also absolute positioned. Then browser order them properly behind each other.
EDIT: Maybe my formatting and styling is not the best for the case, but it was quick update of your code to get the idea
body {
background: #111;
}
.btn {
color: #FFF;
background: #333;
border: none;
font-size: 18px;
font-weight: bold;
padding: 18px 60px;
position: relative;
}
.btn span {
display: block;
content: '';
position: absolute;
top: 18px;
left: 0px;
width: 100%;
text-align: center;
}
.btn:before {
display: block;
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 0;
background: #FFF;
}
.btn:hover {
color: #333;
}
.btn:hover:before {
height: 100%;
}
<br />
<span>Do Stuff</span>
I'm trying to make next animation: logo should be revealed by the div moving down. Div has a transparent background.
Is it possible to hide overlaying part of logo behind transparent div?
<div class="transparent">Some content</div>
<div class="logo"></div>
.transparent { position: relative }
.logo { position: absolute }
I very much doubt if you could clip or mask anything behind a transparent element.
So, perhaps you need to rethink the "hiding behind" part and consider other options.
Perhaps animating the height:
* {
padding: 0;
margin: 0;
}
.transparent {
height: 2em;
line-height: 2em;
border-bottom: 1px solid grey;
position: relative;
}
.logo {
height: 0;
background: orange;
position: absolute;
top: 100%;
width: 100px;
transition: height 0.5s ease;
}
.transparent:hover .logo {
height: 25px; /* assuming height is known */
}
<div class="transparent">Some content
<div class="logo"></div>
</div>
you can try giving visibility hidden property to hide the logo.
visibility:hidden
Maybe an effect like this may help that background of logo is the same as background of the div you are referring to as transparent.
Like this: http://codepen.io/anon/pen/aOwZLJ
You will need to do some complex calculations, if the background is an image, in order to make it look as one element.
You can try this too. Related mostly to hide some part of border.
div {
border-top: 1px solid black;
border-right: 1px solid black;
width: 50px;
height: 50px;
position: relative;
overflow: hidden;
}
div::after {
content: "";
height: 50px;
width: 100%;
border: 1px solid green;
display: block;
position: absolute;
border-right: 0px;
border-top:0px;
border-bottom: 0px;
top: -10px;
}
div::before {
content: "";
height: 50px;
width: 100%;
border: 1px solid green;
display: block;
position: absolute;
border-right: 0px;
border-top:0px;
border-left: 0px;
top: -1px;
left: 10px;
}
<div>
</div>
In 2021, it's actually possible, with some trickery.
First of all, overflow-y:hidden hides something from the bottom... unless it's upside down.
The wrapper should have any height, as long as it can serve as a cut off.
.wrapper {
height: 70px;
position: relative;
overflow-y: hidden;
transform: rotate(180deg);
}
.logo {
animation-name: stretch;
animation-duration: 2s;
animation-timing-function: linear;
transform-origin: top;
}
#keyframes stretch {
0% {
transform: translateY(110px) rotate(180deg);
}
100% {
transform: translateY(40px) rotate(180deg);
}
}
So now the logo will slide down from a seemingly transparent background.
This question already has answers here:
How do I reduce the opacity of an element's background using CSS?
(29 answers)
Closed 9 years ago.
So I have a div with an opacity set with a background image. I want the text that pops up when hovering the div to stay 100%. Could anyone possibly help me with this? Any help would be greatly appreciated!
DEMO
<body>
<div id="container">
<div id="container_inner">
<div id="container_txt">
<p>WORLD OF WARCRAFT</p>
<p id="p_txt">This is a simple World of Warcraft styled div that has been done implementing html, css, and css3</p>
</div>
</div>
</div>
</body>
What I fiddled upon and came on conclusion though is this is what you need I think.
Below is CSS that you have to use.
Fiddle: Click HERE
Demo (Transparent background)
html, body {
margin: 0;
height: 100%;
background-color: #575980;
}
#container {
width: 200px;
height: 300px;
cursor: pointer;
overflow: hidden;
margin: 100px auto;
border: 1px solid #333;
background-color: #000;
box-shadow: 0px 2px 8px #111;
}
#container_inner {
opacity: .8;
margin: auto;
width: 200px;
height: 300px;
transition: .5s;
position: relative;
background-color: #FFF;
background-image: url('http://static.mmo-champion.com/mmoc/images/news/2010/march/ss973.jpg');
background-size: 200% 100%;
background-position: 60% 50%;
box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.5);
}
#container_inner:hover, #container_txt:hover {
opacity: 1;
}
#container_txt {
color: #fff;
height: 0px;
bottom: 0px;
width: 200px;
transition: .2s;
position: absolute;
font: normal 1em calibri;
background-color: rgba(0, 0, 0, 1);
}
#container_inner:hover #container_txt {
height: 100px;
opacity: 1;
}
p {
top: -5px;
padding: 0px 10px;
position: relative;
}
p a {
color: #fff;
text-decoration: none;
}
#p_txt {
top: -15px;
position: relative;
font-size: 12px;
}
Just for a better understanding:
This CSS changes the opacity of the complete element (background, border, text, containing child-elements, ...)
#container{
background-color: #000;
opacity: 0.5;
}
But this CSS changes the opacity of a color. And this "modified" color will be used for background.
#container{
background-color: rgba(0, 0, 0, 0.5);
}
The problem is that a child cannot be less opaque than its parent. In this case, instead of a background image, I would use a :after pseudo element to create the background, then put the background image/opacity/ whatever on that, and leave the parent alone.
I modified your fiddle to do this (http://jsfiddle.net/srfGg/4/), but the main key is:
#container_inner:after{
opacity:0.8;
transition:.2s;
content: "";
display:block;
color:#FFF;
height:100%;
width:100%;
position: aboslute;
top:0;left:0;right:0;bottom:0;
background-color: #FFF;
background-image: url('http://static.mmo-champion.com/mmoc/images/news/2010/march/ss973.jpg');
background-size: 200% 100%;
background-position: 60% 50%;
}
#container_inner:hover:after, #container_txt:hover {
opacity: 1;
}