I prefer CSS only solution; I can change HTML structure; Always only single line of text
TL;DR;
How to hide top part of text instead of bottom:
div {
overflow: hidden;
height: 11px;
}
<div>HOME</div>
Full example
I want to hide top of the text line so I can simulate transition effect:
div {
height: 20px;
width: 100px;
text-align: center;
}
div span {
display: block;
overflow: hidden;
transition: all 500ms ease-in-out;
height: 20px;
}
div .default {
color: black;
background-color: #f0f0f0;
}
div .hover {
height: 0;
color: white;
background-color: black;
}
div:hover .hover {
height: 25px;
}
div:hover .default {
height: 0px;
}
<div>
<span class="default">HOME</span>
<span class="hover">HOME</span>
</div>
As you can see in example .hover is currently sliding from bottom because text is hidden from bottom to top when height is reduced.
I want to hide text from top to bottom, so that it will look like same text is inverting it's color.
Are you against if I use pseudo elements to do it ? I play with bottom height to make it appears from top to bottom with the text in content property.
div .default {
display: block;
overflow: hidden;
height: 20px;
position: relative;
color: black;
background-color: #f0f0f0;
}
div .default:after { content: "Home"; position: absolute; left: 0; bottom: 100%; right: 0; background: #000; color: #fff; text-transform: uppercase; transition: all 500ms ease-in-out;}
div .default:hover:after { bottom: 0; }
HTML
<div>
<span class="default">HOME</span>
</div>
Like this
Other solution keeping the structure and avoid text in content property
<div>
<span class="default">HOME</span>
<span class="black">HOME</span>
</div>
CSS
div .black { position: absolute; left: 0; bottom: 100%; right: 0; background: #000; color: #fff; text-transform: uppercase; transition: all 500ms ease-in-out;}
div .default:hover ~ .black { bottom: 0; }
Fiddle with 2nd solution
I have solved that by using absolute positioned element over origin item:
div {
height: 20px;
width: 100px;
text-align: center;
position: relative;
}
div span {
display: block;
overflow: hidden;
transition: all 500ms ease-in-out;
height: 20px;
}
div .default {
color: black;
background-color: #f0f0f0;
/* ADDED */
position: absolute;
left: 0;
z-index: 10;
top: 0;
width: 100%;
height: 100%;
}
div .hover {
height: 20px;
color: white;
background-color: black;
}
div:hover .default {
height: 0px;
}
<div>
<span class="default">HOME</span>
<span class="hover">HOME</span>
</div>
Given your first example, this one hides top part of the text. Just play around with the line-height on your animation
Just add on your div span style:
line-height: 5px; /* play with the value till desired look is reached*/
https://jsfiddle.net/w0ydLg9h/
Related
This question already has answers here:
Position absolute but relative to parent
(5 answers)
Closed 9 months ago.
I am trying to animate background-color property on hovering from bottom to top and again from bottom to top when mouse is out. I have this pen, but it seems like width: 100% and height: 100% in ::after is calculated based on <p> tag, not <span>.
So how can I fix it? I want background-color animation just on underlined text (dolor), not for the whole paragraph.
div {
display: flex;
align-items: center;
justify-content: center;
}
p {
position: relative;
font: 2em sans-serif;
}
.underlined {
font-weight: bold;
text-decoration: underline solid black 0.1em;
transition: color 0.25s ease-out;
}
.underlined::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%; /* 100% of <p>, not <span> */
height: 100%; /* 100% of <p>, not <span> */
background: black;
z-index: -1;
transform: scaleY(0);
transform-origin: top;
transition: transform 0.25s ease-out;
}
.underlined:hover {
color: white;
}
.underlined:hover::after {
transform: scaleY(1);
transform-origin: bottom;
}
.underlined:hover::selection {
color: black;
background: white;
}
<div>
<p>Lorem ipsum <span class="underlined">dolor</span> sit amet</p>
</div>
add a position to <span> with class .underlined
.underlined {
position: relative;
}
.main-nav-link {
color: #0F1D4A;
font-size: 1rem;
font-weight: 700;
display: flex;
flex-direction: column;
}
.under-line::after {
height: 5px;
background: #6ECDE5;
width: 0px;
position: absolute;
content: "";
transition: all 0.2s ease;
}
.main-nav-link:hover{
.under-line{
&::after {
width: 100%;
}
}
}
<a class="main-nav-link" href="https://happytots.a101.co/shop/">All<span class="under-line"></span></a>
I am trying to create an effect when div class="container" is being hovered, a smooth upper transition occurs of another div from bottom. Only during hover, this should happen cause I want that .bottom div to be hidden. When that div is not hidden, I can see the effect as I want. But as I hide the bottom div, that hovering effect smooth transition effect cannot be seen. Check this code once.
HTML CODE
<div class="box">
Hello
<div class="bottom">
Everyone
</div>
</div>
CSS code
.box{
border: 1px solid black;
display: inline-block;
border-radius: 3px;
padding: 8px;
font-size: 20px;
}
.bottom {
background: pink;
width: 80px;
text-align: center;
position: absolute;
top:80px;
left:0;
/* display: none; */
}
.box:hover .bottom {
display: block;
transition: linear 0.2s;
top:55px;
}
Here is the codepen link
https://codepen.io/Biebk/pen/MWpREqb
First off, rather than display: none to hide the incoming element altogether, you can set its opacity to 0, and then when the parent is hovered, set it to 1, like so:
.bottom {
opacity: 0;
}
.box:hover .bottom {
opacity: 1;
}
I suppose that given you want an incoming "pull-up" effect on hover, you want to that element to also "pull-down" when the hover ends. You can reverse the same effect by using a :not(:hover) on the parent element:
.box:not(:hover) .bottom {
opacity: 0;
}
Also, be sure to set the transition on the non-hovered state. The following example provides the smooth transition you're looking for:
.box {
border: 1px solid black;
display: inline-block;
border-radius: 3px;
padding: 8px;
font-size: 20px;
}
.bottom {
background: pink;
width: 80px;
text-align: center;
position: absolute;
left: 0;
transition: all .25s ease;
}
.box:not(:hover) .bottom {
top: 80px;
opacity: 0;
}
.box:hover .bottom {
top: 55px;
opacity: 1;
}
<div class="box">
Hello
<div class="bottom">
Everyone
</div>
</div>
A secondary approach would be to place the bottom div as a sibling to the box, and use the adjacent sibling combinator to apply the hover effects:
.box {
border: 1px solid black;
display: inline-block;
border-radius: 3px;
padding: 8px;
font-size: 20px;
}
.bottom {
font-size: 20px;
background: pink;
width: 80px;
text-align: center;
position: absolute;
left: 0;
top: 80px;
opacity: 0;
cursor: default;
transition: all .25s ease;
}
.box:hover + .bottom {
top: 55px;
opacity: 1;
}
<div class="box">
Hello
</div>
<div class="bottom">
Everyone
</div>
Use opacity property rather than display to achieve the desired effect, then
use the following code
.box {
border: 1px solid black;
display: inline-block;
border-radius: 3px;
padding: 8px;
font-size: 20px;
}
.bottom {
background: pink;
width: 80px;
text-align: center;
position: absolute;
top: 80px;
left: 0;
opacity: 0;
}
.box:hover .bottom{
opacity: 1;
transition: opacity 0.2s , top 1s;
top: 55px;
}
Use the following code.
.box {
border: 1px solid black;
display: inline-block;
border-radius: 3px;
padding: 8px;
font-size: 20px;
}
.hovered{
transition: all .2s;
}
.bottom {
background: pink;
width: 80px;
text-align: center;
position: absolute;
top: 80px;
left: 0;
visibility: hidden;
}
.hovered:hover+.bottom {
transition: all .2s;
top: 55px;
visibility: visible;
}
<div class="box">
<div class="hovered">Hello</div>
<div class="bottom">
Everyone
</div>
</div>
I am trying to have a square-shaped div (the red box) on the page by default. When the user hover the mouse over it, a second div should display with a semi-transparent black background and some text/content. I'm trying to imitate Devon Stank's project section on his website.
The code I have right now increases the height of the default square red box and the second div doesn't cover the whole of the red box. What's wrong with the code?
Fiddle
.project-box {
position: relative;
width: 30%;
padding-top: 30%;
overflow: hidden;
margin-right: 20px;
margin-bottom: 15px;
display: inline-block;
}
.default-box {
background-color: red;
}
.hover-content {
position: relative;
width: 100%;
height: 100%;
padding-top: 30%;
overflow: hidden;
display: inline-block;
}
.default-hover {
opacity: 0;
-webkit-transition: 0.5s;
-moz-transition: 0.5s;
-o-transition: 0.5s;
-ms-transition: 0.5s;
transition: 0.5s;
background-color: rgba(0, 0, 0, 0.5);
}
.default-box:hover .default-hover {
opacity: 1;
}
<div class="default-box project-box">
<div class="default-hover hover-content">hello</div>
</div>
height: 100%; won't work on the element if the parent's height isn't defined.
Also, if you stick with position: relative with a padding on the parent, you won't be able to cover it all.
If you want to cover all the .project-box (parent) no matter its padding values,
I suggest you to use an absolute positioning on its child:
(I've done it by adding the new class .veil, but it could be done within your existing class)
.project-box {
position: relative; /* ADDED so that the absolute positioning refers to this parent */
width: 30%;
padding-top: 30%;
overflow: hidden;
margin-right: 20px;
margin-bottom: 15px;
display: inline-block;
}
.default-box {
background-color: red;
}
.hover-content {
/* REMOVED position and sizes */
padding-top: 30%;
overflow: hidden;
display: inline-block;
}
.default-hover {
opacity: 0;
transition: 0.5s;
background-color: rgba(0, 0, 0, 0.5);
}
.default-box:hover .default-hover {
opacity: 1;
}
/* ADDED this class */
.veil {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<div class="default-box project-box">
<!-- Added a class for the child here -->
<div class="default-hover hover-content veil">hello</div>
</div>
Hope it helps.
Here, it may help you, try it.
.project-box {
position: relative;
width: 30%;
height:100%
}
.default-box {
background-color: red;
}
.hover-content {
position: relative;
width: 100%;
height: 100%;
text-align:center;
padding-top: 30%;
}
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>
Hallo I am trying to create a button aligned to the right of the screen which leads to the next article.
Everything works as I want it, till the point when I add the css transition.
As you can see in the fiddle I have twice the exact same code, except that the blue bar does have a css transition property and the green bar does not have a transition.
I am using the 64bit version of chrome (45.0.2453.0 dev-m) and while in here the green bar works as supposed when hovered, the content from the blue bar with the transition does have some major alignment bug. It seems that the content of the containers pops out of the containers.
<nav class="nav-next">
<a href="link" class="link">
<div class="thumbnail">
<img width="100" height="100" src="http://travelwithoutplan.com/wp-content/uploads/DSC01985_Vibrance-100-200x200.jpg" class="attachment-100x100 wp-post-image" alt="DSC01985 Vibrance 100" />
</div>
<div class="headline">Travel Information for Liechtenstein</div>
</a>
</nav>
CSS (without transition it works - but with transition it causes an alignment bug)
/*
.nav-next {
-moz-transition: width .5s;
-o-transition: width .5s;
-webkit-transition: width .5s;
transition: width .5s;
}
*/
.nav-next {
background-color: lightblue;
overflow: hidden;
position: fixed;
top: 50px;
left: auto;
right: 0;
box-sizing: border-box;
width: 30px;
height: 120px;
}
.nav-next:hover {
width: 330px;
}
.nav-next .headline:after, .nav-next .link {
display: block;
border-top: 1px solid #8c8c8c;
}
.nav-next .link {
background: #fff;
height: 120px;
width: 300px;
box-sizing: border-box;
padding: 10px;
position: absolute;
right: 0;
top: 0;
margin-left: 30px;
margin-right: 30px;
border: 1px solid #8c8c8c;
border-right: none;
}
.nav-next:hover .link {
margin-left: 0;
}
.nav-next .link:before {
color: #262626;
left: auto;
right: -23px;
position: absolute;
top: 52px;
font-size: 16px;
font-size: 1rem;
content: "\e12e";
font-family: wp-svg-plugin-icon-set1!important;
}
.nav-next .thumbnail {
position: relative;
width: 100px;
float: left;
margin-left: 0;
margin-right: 5px;
}
.nav-next .headline {
color: #595959;
height: 100px;
overflow: hidden;
padding-right: 10px;
padding-top: 5px;
position: relative;
left: 4px;
right: 0;
font-size: 14px;
}
.nav-next .headline:after {
content: "Next Article";
position: absolute;
width: 100%;
bottom: 0;
padding-top: 5px;
text-align: right;
}
http://jsfiddle.net/64g0vzq1/4/
Here you can see how with Chrome 64bit-version (45.0.2453.0 dev-m) the aligment of the content from the hovered blue bar (with css transition) is wrong. The text disappears behind the image, the image positionig is wrong etc.
Below the content of the green bar (without css transition) is shown correctly.
Is this a css error or something? How can I fix it?
Many thanks in advance!