Button masked transition - css

I want a button hover transition using an (I think) mask in the background.
A button that in normal state has a white background and black letters would have a black background sliding in from the side on hover making the letters white on the go. Like so:
I got it working using a before and after pseudo:
.button--slide {
background-color: #fff;
color: #000;
border-radius: 10px;
border: none;
padding: 10px 20px;
position: relative;
transition: all 0.5s ease;
cursor: pointer;
overflow: hidden;
}
.button--slide span {
position: relative;
z-index: 999;
}
.button--slide:before {
content: "";
width: 100%;
height: 100%;
position: absolute;
left: calc(-100% - 35px);
top: 0;
background-color: #000;
transition: left 0.5s ease;
}
.button--slide:after {
content: "";
position: absolute;
top: 0;
left: -70px;
width: 0px;
height: 0px;
border-left: 35px solid transparent;
border-right: 35px solid transparent;
border-top: 35px solid #000;
transition: left 0.5s ease;
}
.button--slide:hover {
color: #fff;
}
.button--slide:hover:before {
left: 0;
}
.button--slide:hover:after {
left: calc(100% - 35px);
}
See fiddle https://jsfiddle.net/5arj1emx/
It's not quite how I want it: I would like the background to mask the letters like in the example so that the letters turn white as the black background slides over it.
Is this possible?

do a background animation for both the pseudo element and the span and make the one of the span to color the text. I used a big transition time to better see the result;
body {
background-color: #efefef
}
.button--slide {
background-color: #fff;
color: #000;
border-radius: 10px;
padding:0;
border: none;
position: relative;
cursor: pointer;
overflow: hidden;
}
.button--slide span {
display:block;
padding: 10px 20px;
position: relative;
transition: all 5s ease;
color:transparent;
font-weight:bold;
background:linear-gradient(-45deg,#000 50%,#fff 0) right/220% 100% no-repeat;
-webkit-background-clip:text;
background-clip:text;
}
.button--slide:before {
content: "";
width: 100%;
position: absolute;
left: 0;
top: 0;
bottom:0;
background:linear-gradient(-45deg,transparent 50%,#000 0) right/220% 100% no-repeat;
transition: 5s ease;
}
.button--slide:hover span,
.button--slide:hover:before {
background-position:left;
}
<button class="button--slide">
<span>SEE OUR GLOBES</span>
</button>

Related

How to place line underneath the circle? without z-index

I made an X with a circle using css.
There is a green line that is sticking out on top of the circle, how do I place it under the circle?
How would this be done?
code: https://jsfiddle.net/6wod3pLm/
That is all I am doing in the code.
.exitnew {
-webkit-appearance: none;
appearance: none;
position: relative;
box-sizing: border-box;
margin: auto;
padding: 0;
width: 48px;
height: 48px;
cursor: pointer;
background: blue;
border: none;
border-radius: 50%;
clip-path: circle(50%);
transition: all 1s ease;
overflow: hidden;
}
.exitnew:before,
.exitnew:after {
content: "";
position: absolute;
height: 5px;
top: 22px;
left: -1px;
right: -1px;
background: green;
transform: rotate(45deg);
transition: all 1s ease;
}
.exitnew:after {
transform: rotate(-45deg);
}
.exitnew:hover {
background: transparent;
}
.exitnew:hover:before,
.exitnew:hover:after {
background: green;
}
.exitnew b {
box-sizing: border-box;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border: 5px solid red;
border-radius: 50%;
}
<button class="exitnew" type="button" aria-label="Close"><b></b></button>
You don't need all these code. Here is an easier idea:
.exitnew {
-webkit-appearance: none;
appearance: none;
box-sizing: border-box;
margin: 0;
padding: 0;
width: 48px;
height: 48px;
cursor: pointer;
--b:7px; /* the thickness*/
--c:blue 90deg,green 0; /* the coloration */
background:
conic-gradient(from 90deg at var(--b) var(--b),var(--c))
calc(100% + var(--b)/2) calc(100% + var(--b)/2)/
calc(50% + var(--b)) calc(50% + var(--b));
border: 5px solid red;;
border-radius: 50%;
transform:rotate(45deg);
}
<button class="exitnew" type="button" aria-label="Close"></button>
You just need to use z-index property on the :after CSS selector:
.exitnew {
-webkit-appearance: none;
appearance: none;
position: relative;
box-sizing: border-box;
margin: auto;
padding: 0;
width: 48px;
height: 48px;
cursor: pointer;
background: blue;
border: none;
border-radius: 50%;
clip-path: circle(50%);
transition: all 1s ease;
overflow: hidden;
}
.exitnew:before,
.exitnew:after {
content: "";
position: absolute;
height: 5px;
top: 22px;
left: -1px;
right: -1px;
background: green;
transform: rotate(45deg);
transition: all 1s ease;
z-index: -1
}
.exitnew:after {
transform: rotate(-45deg);
}
.exitnew:hover {
background: transparent;
}
.exitnew:hover:before,
.exitnew:hover:after {
background: green;
}
.exitnew b {
box-sizing: border-box;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border: 5px solid red;
border-radius: 50%;
}
<button class="exitnew" type="button" aria-label="Close"><b></b></button>
:before and :after are like html bread on you element sandwich. :before is the bottom slice, and :after is the top slice.
Add a negative z-index to the :before, :after styles and that will position your :after behind the button the same as the :before.
.exitnew:before,
.exitnew:after {
content: "";
position: absolute;
height: 5px;
top: 22px;
left: -1px;
right: -1px;
background: green;
transform: rotate(45deg);
transition: all 1s ease;
z-index: -1;
}
EDIT WITHOUT Z-INDEX
.exitnew {
-webkit-appearance: none;
appearance: none;
position: relative;
box-sizing: border-box;
margin: auto;
padding: 0;
width: 48px;
height: 48px;
cursor: pointer;
background: blue;
border: none;
border-radius: 50%;
clip-path: circle(50%);
transition: all 1s ease;
overflow: hidden;
}
.exitnew:before,
.exitnew:after {
content: "";
position: absolute;
height: 5px;
width: 38px;
top: 22px;
left: 5px;
right: 5px;
background: green;
transform: rotate(45deg);
transition: all 1s ease;
}
.exitnew:after {
transform: rotate(-45deg);
}
.exitnew:hover {
background: transparent;
}
.exitnew:hover:before,
.exitnew:hover:after {
background: green;
}
.exitnew b {
box-sizing: border-box;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border: 5px solid red;
border-radius: 50%;
}
<button class="exitnew" type="button" aria-label="Close"><b></b></button>
You can set the z-index property to send the green line(s) backward, "behind" the circle:
.exitnew:before,
.exitnew:after {
content: "";
position: absolute;
height: 5px;
top: 22px;
left: -1px;
right: -1px;
background: green;
transform: rotate(45deg);
transition: all 1s ease;
z-index: -1;
}
here's an example: https://jsfiddle.net/q7zprh4w/
This is a solution without b and z-index:
.exitnew {
position: relative;
width: 48px;
height: 48px;
border: 5px solid red;
border-radius: 50%;
background-color: blue;
}
.exitnew::before {
content: "";
display: block;
position: absolute;
width: 10.416%;
height: 100%;
top: 0;
left: 44.792%;
background-color: green;
transform: rotate(45deg);
}
.exitnew::after {
content: "";
display: block;
position: absolute;
width: 10.416%;
height: 100%;
top: 0;
left: 44.792%;
background-color: green;
transform: rotate(-45deg);
}
I put the red border to the button itself. So the two pseudo element ::before and ::after aren't overlapping the red border.
Note: I don't use box-sizing: border-box

CSS - yet another transition not working question

Trying to understand transition css property, but can't seem to figure out why this code is not working. Border needs to go from solid to dotted
.home {
color: #ff652f;
font-weight: 700;
border-bottom: 18px solid #ff652f;
-webkit-transition: border-bottom 3s ease-in-out;
transition: border-bottom 3s ease-in-out;
}
.home {
border-bottom: 18px dashed #ff652f;
}
Made a jsfiddle here - https://jsfiddle.net/h7925b8g/
Would like the transition to happen slowly. Any ideas what I am doing wrong? Any help is greatly appreciated!
As mentioned in comments, border-style is not animatable, so you can't simply use the transition property to change it.
Instead, you can fake it. How exactly you pull this off depends on what you want the transition to look like. One approach is to use a repeating linear-gradient for the dashed effect and then transition that to overlay the border (either a literal border or just some other element that acts like a border).
For example, sliding up from the bottom:
.home {
color: #ff652f;
font-weight: 700;
width: 200px;
padding-bottom: 10px;
position: relative;
}
.home::before,
.home::after {
content: '';
display: block;
width: 100%;
position: absolute;
bottom: 0;
left: 0;
}
.home::before {
height: 10px;
background-color: orange;
z-index: 0;
}
.home::after {
height: 0px;
transition: height 350ms ease;
background-image: linear-gradient(to right, white 0px 10px, orange 10px 20px, white 20px);
background-size: 20px 100%;
background-repeat: repeat;
z-index: 1;
}
.home:hover::after {
height: 10px;
}
<div class="home">Hover me!</div>
Or sliding in from the left:
.home {
color: #ff652f;
font-weight: 700;
width: 200px;
padding-bottom: 10px;
position: relative;
}
.border-animation {
display: block;
position: absolute;
bottom: 0;
left: 0;
z-index: 0;
width: 100%;
height: 10px;
overflow: hidden;
background-color: orange;
}
.border-animation::after {
content: '';
display: block;
width: 100%;
height: 100%;
position: absolute;
bottom: 0;
left: 0;
z-index: 1;
background-image: linear-gradient(to right, white 0px 10px, orange 10px 20px, white 20px);
background-size: 20px 100%;
background-repeat: repeat;
transform: translateX(-100%);
transition: transform 350ms ease;
}
.home:hover .border-animation::after {
transform: translateX(0);
}
<div class="home">Hover me!<span class="border-animation"></span></div>

How to draw a line using pseudo element right below text and ignore the padding?

I want to draw a line below a link and apply animation on it, so I use pseudo element. It produces the line as expected, but if there is a large padding around the link, the line appears far away. Is there a way to ignore the padding and draw the line right below text?
a {
position: absolute;
padding: 20px 0;
top: 50%;
left: 50%;
margin-top: -30px;
margin-left: -30px;
line-height: 20px;
}
a:after {
position: absolute;
bottom: 0;
left: 0;
width: 0;
content: '';
transition: width .3s;
display: block;
}
a:hover:after {
width: 100%;
border-top: 1px solid #333;
}
<a>Link Text</a>
You can just remove the absolute position since the pseudo is set on :after so that it's placed right after the text.
a {
position: absolute;
padding: 20px 0;
top: 50%;
left: 50%;
margin-top: -30px;
margin-left: -30px;
line-height: 20px;
border: 1px solid aqua;
}
a:after {
content: "";
display: block;
border-top: 1px solid #333;
width: 0;
transition: width .3s;
}
a:hover:after {
width: 100%;
}
<a>Link Text</a>
Side note, you might encounter the double tap behavior for the kind of hover effects on touch devices such as phones, tablets. Add this to fix that:
#media (hover: none) {
a:hover:after {
display: none;
}
}
In addition, the effects can also be done with linear-gradient(), example:
a {
display: inline-block;
text-decoration: none;
border: 1px solid aqua;
font-size: 16px;
padding: 20px 0;
background-image: linear-gradient(to bottom, blue, blue);
background-position: 0 38px; /*adjust this based on font-size and padding*/
background-size: 0 1px;
background-repeat: no-repeat;
transition: background-size .3s;
}
a:hover {
background-size: 100% 1px;
}
Link text

CSS: How do I make the lines in this hover effect stay with the word inside of it?

This is my modification of someone else's hover effect. So I am not familiar with the working of btn-2 class.(I don't know the syntax used)
Here is my CSS code:
* {
box-sizing: inherit;
transition-property: all;
transition-duration: .6s;
transition-timing-function: ease;
}
body {
background-color: black;
}
a {
text-decoration: none;
color: tomato;
font-size: 50px;
font-family: 'Oswald', sans-serif;
}
.container {
padding: 1em;
text-align: center;
vertical-align: middle;
}
.btn-2 {
letter-spacing: 10px;
}
.btn-2:hover,
.btn-2:active {
letter-spacing: 30px;
}
.btn-2:after,
.btn-2:before {
border: 1px solid rgba(tomato, 0);
bottom: 2px;
top: 2px;
content: " ";
display: block;
margin: 0 auto;
position: relative;
transition: all 280ms ease-in-out;
width: 0;
}
.btn-2:hover:after,
.btn-2:hover:before {
backface-visibility: hidden;
border-color: tomato;
transition: width 350ms ease-in-out;
width: 50%;
}
.btn-2:hover:before {
bottom: auto;
top: 0;
width: 50%;
}
I want to use the effect for button in my navigation bar. But I have 3 problems to solve:
I want the lines above and below the word that appear when you hover it to be of the same width as the word.
I want the word to be centered relative to the line. That is, the line should grow out from the middle point of the word.
The lines isn't going where the word is going.
Some discoveries I make, which I don't know the cause of:
The 2 lines will be longer when .comtainer{padding=1em} than 5em.
When I delete text-align and vertical-align in the .container class, the hovering lines stay centered, but the word goes to the left of the window.
I'm not sure how good I understand you, but here some example I made
a {
color: #333;
display: inline-block;
padding: 15px 0;
position: relative;
text-align: center;
text-decoration: none;
transition: all 250ms ease-in-out;
&:before,
&:after{
content: '';
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
width: 0;
height: 2px;
background-color: #333;
transition: all 250ms ease-in-out;
}
&:before {
top:0;
}
&:after {
bottom: 0;
}
&:hover {
letter-spacing: 5px;
&:before,
&:after {
width: 100%;
}
}
//Trick is here
span {
&:before {
content:attr(title);;
letter-spacing: 5px;
display:block;
height:1px;
color:transparent;
overflow:hidden;
visibility:hidden;
margin-bottom:-1px;
}
}
}
<span title="Hover Me">Hover Me</span>
You can check my example here

formatting image hover text

I know this is a simple formatting question, but I need to format some text inside a hover box over an image. I want to separate the hover text into two paragraphs, and the hover text is not covering the entire image for some reason...below is my hover CSS:
ul.img-list {
list-style-type: none;
margin: 0;
padding: 0;
text-align: left;
}
ul.img-list li {
display: inline-block;
height: auto;
margin: ;
position: relative;
width: 100%;
}
span.text-content {
background: rgba(0,0,0,0.5);
color: white;
display: table;
height: 100%;
left: 0;
position: justify;
top: 0;
width: 75%;
}
span.text-content span {
display: ;
text-align: center;
vertical-align: middle;
}
span.text-content {
background: rgba(0,0,0,0.5);
color: white;
display: table;
height: auto;
left: 0;
position: justify;
top: ;
width:100%;
opacity: 0;
}
ul.img-list li:hover span.text-content {
opacity: 1;
}
span.text-content {
background: rgba(0,0,0,0,5);
color: white;
display: ;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
opacity: 0;
-webkit-transition: opacity 2000ms;
-moz-transition: opacity 2000ms;
-o-transition: opacity 2000ms;
transition: opacity 2000ms;
}
You can do something like this code example here: JSFiddle
HTML:
<span class="tooltip" data-tooltip="I'm small tooltip. Don't kill me!">Hover me!</span>
CSS:
.tooltip {
border-bottom: 1px dotted #0077AA;
cursor: help;
}
.tooltip::after {
background: rgba(0, 0, 0, 0.8);
border-radius: 8px 8px 8px 0px;
box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.5);
color: #FFF;
content: attr(data-tooltip); /* The main part of the code, determining the content of the pop-up prompt */
margin-top: -24px;
opacity: 0; /* Our element is transparent... */
padding: 3px 7px;
position: absolute;
visibility: hidden; /* ...and hidden. */
transition: all 0.4s ease-in-out; /* To add some smoothness */
}
.tooltip:hover::after {
opacity: 1; /* Make it visible */
visibility: visible;
}

Resources