I add a ":after" element to all links (simulate a "border-bottom") so on ":hover" i can animate this pseudo element ("height: 100%"). This works fine, but when the link is split with a line-break the pseudo element is broken after the line break.
a {
color: red;
position: relative;
text-decoration: none;
&:after {
transition: height .1s;
background-color: red;
bottom: -3px;
content: '';
display: inline;
height: 3px;
left: 0;
right: 0;
position: absolute;
width: 100%;
z-index: -1;
}
&:hover:after {
height: calc(100% + 4px);
}
&:hover {
color: white;
}
}
Here is a pen:
http://codepen.io/herrfischer/pen/YWKmQJ
Any idea what I am doing wrong?
For an inline element, background will be more efficient: http://codepen.io/gc-nomade/pen/pbzMYP
a {
color: red;
position: relative;
text-decoration: none;
background:linear-gradient(red,red) bottom repeat-x;
background-size:3px 3px;
transition:1s;
&:hover {
background-size:100% 100%;
color: white;
}
}
Stolen from another site - it works with animated background gradient :)
a {
background-image: linear-gradient(red 0%, red 100%);
background-position: bottom;
background-repeat: repeat-x;
background-size: 0 0;
border-bottom: 3px solid red;
color: red;
position: relative;
text-decoration: none;
transition: 150ms ease;
&:hover {
color: white;
background-size: 1em 1.5em;
}
}
Updated the pen.
Related
I wanted my button to change the background color on hover with a transition from left to right. This is what I tried:
.btn {
background-color: transparent;
transition-property: background-color, left, right;
transition-duration: 1s;
color: #007eb6;
border: 1px solid #007eb6;
&:hover {
background-color: #007eb6;
color: #fafafa;
border: 1px solid #007eb6;
}
Here is a codepen you can use (Its not mine)
The trick is to set background-position to 0% and on hover change it to 100%
<button>Bangladesh</button>
CSS Code
button {
background-color: red;
color: #fff;
border: none;
outline: none;
padding: 20px 60px;
font-size: 20px;
text-transform: uppercase;
position: relative;
z-index: 1;
cursor: pointer;
}
button::before {
content: "";
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 0;
background-color: green;
transition: .5s;
z-index: -1;
}
button:hover::before {
width: 100%;
}
I was playing around with CSS animations to get some eye candy - and I found following result pretty nice:
body {
font-size: xx-large;
font-family: 'Courier New';
color: white;
background: black;
}
a {
text-decoration: none;
position: relative;
}
a:visited {
color: white;
}
a::before,
a::after {
content: '';
position: absolute;
bottom: 0;
right: 50%;
width: 0;
border-bottom: 2px solid blue;
transition: 400ms 200ms;
}
a::after {
left: 50%;
right: 0;
}
a:hover::before,
a:hover::after {
width: 50%;
}
This is a test. This line has to be a bit longer to see the effect.
The problem with it, is its behaviour on line breaks... Can this be fixed? I would already be happy, if the animation is only on the hovered clientRect and once it is finished, all other clientRects get just underlined. A CSS-only solution (if there is one) would be highly appreciated.
I could find a solution by modifying Nicky Meuleman's example (thanks to webdev-dan for providing that link):
body {
background-color: black;
font-size: 3rem;
}
a {
color: blue;
text-decoration: none;
background-image: linear-gradient(blue, blue), linear-gradient(blue, blue);
background-size: 0 2px, 0 2px;
background-position: 50% 100%, 50% 100%;
background-repeat: no-repeat;
transition: background-size 400ms linear, background-position 400ms linear;
transition-delay: 200ms;
}
a:hover {
background-size: 50% 2px, 100% 2px;
background-position: 0 100%, 50% 100%;
}
a:visited {
color: white;
}
Short link test.
This link is a bit longer to see the multiline behaviour.
Hope this is useful to others too. :-)
I have a div element inside of it I have some links. I want the colour of the div to change on mouse hover not to full length of width but only 25% of the div.
When I use the hover properties, it changes the colour of the entire div.
Also please suggest which tag I should put my hover properties- span tag or a tag.
How can I get a smooth transition animation during the colour change?
.c-label {
display: inline-block;
text-align: left;
}
.cloud-label {
display: inline-block;
float: left;
margin: 5px 0;
opacity: 1;
width: 50%;
line-height: 1.2;
font-size: 120%;
text-align: left;
}
.cloud-label a {
transition: all 0.5s;
background: #000;
border-radius: 3px;
color: #fff;
display: block;
font-size: 14px;
padding: 7px 20px;
position: relative;
margin-left: 20px;
text-decoration: none;
transition: color .15s linear;
-webkit-transition: color .15s linear;
-moz-transition: color .15s linear;
}
.cloud-label a::before {
content: "";
display: block;
border-style: solid;
border-color: transparent #138D89 transparent transparent;
border-width: 15.2px;
width: 0px;
left: 0px;
position: absolute;
margin-left: -29px;
margin-top: -15px;
top: 50%;
}
.cloud-label a::after {
content: "";
display: block;
position: absolute;
width: 8px;
height: 8px;
background-color: #fff;
border-radius: 50%;
top: 50%;
margin-top: -4px;
left: -3px;
}
.cloud-label :hover {
background-color: #138D89;
}
<div class="c-label">
<span class="cloud-label">
Gadgets
</span>
</div>
not to full length of width but only 25% of the div
You can use linear-gradient for this.
Also please suggest which tag I should put my hover properties- span tag or a tag
In principle, this does not require additional tags
How can I get a smooth transition animation during the colour change?
When hovering, you need to change the property background-position from one to other side (for example, from left to right).
Result
.link {
position: relative;
display: inline-block;
margin-left: 10px;
padding: 5px 10px;
color: #fff;
font-weight: 700;
text-decoration: none;
background: linear-gradient(to left, #138D89 25%, #000 25%) left / 135% 100% no-repeat;
transition: 0.3s;
}
.link:hover {
background: linear-gradient(to left, #138D89 25%, #000 25%) right / 135% 100% no-repeat;
}
.link::before {
content: "";
position: absolute;
top: 0;
right: 100%;
border-right: 15px solid #138D89;
border-top: 13px solid transparent;
border-bottom: 15px solid transparent;
}
.link::after {
content: "";
position: absolute;
top: 50%;
left: 0;
transform: translate(-50%, -50%);
width: 10px;
height: 10px;
box-sizing: border-box;
background: #fff;
border-radius: 50%;
}
<a class="link" href="">Lorem ipsum dolor sit amet.</a>
And same code on CodePen
I have an element with background set as color
On hover background is set as radial-gradient
I want to make transition between colors on hover but it creates weird effect where my element disappear for a second.
Here is link
Link
Is it possible to switch between color and gradient without this problem?
.link {
display: block;
position: absolute;
bottom: 20%;
padding: 0 25px;
height: 42px;
line-height: 42px;
border-radius: 8px;
font-size: 15px;
font-weight: 700;
background: red;
color: white;
transition: all 0.3s ease-in-out;
}
.link:hover {
text-decoration: none;
background: radial-gradient(98px 98px at center center, red 0%, #0088b5 100%);
}
You can play with background-size:
.link {
display: inline-block;
padding: 0 25px;
line-height: 42px;
border-radius: 8px;
font-size: 15px;
font-weight: 700;
background-image: radial-gradient(circle,red 0%, #0088b5 100%);
background-position:center;
background-size:600% 600%; /*a big size to see only the red*/
color: white;
text-decoration: none;
transition: all 0.3s ease-in-out;
}
.link:hover {
background-size:150% 150%; /* reduce the size to see the gadient effect*/
}
<div class="link">Link</div>
You can use the :before pseudo-element along with a transition on the opacity of the background color to get this effect.
Credit: Dave Lunny.
Also, check out this previous question.
.link {
display: block;
position: absolute;
bottom: 20%;
padding: 0 25px;
height: 42px;
line-height: 42px;
border-radius: 8px;
font-size: 15px;
font-weight: 700;
background: rgba(255, 0, 0, 1);
color: white;
opacity: 1;
transition: all 0.3s ease-in-out;
}
.link:before {
border-radius: inherit;
content: '';
display: block;
height: 100%;
position: absolute;
top: 0; left: 0;
width: 100%;
z-index: -100;
background: radial-gradient(98px 98px at center center, red 0%, #0088b5 100%);
}
.link:hover {
text-decoration: none;
background: rgba(255, 0, 0, 0);
}
<a class="link" href="#">Hover Me!</a>
I need to create the button styles in the image below (the one on the right is transparent, not white).
The bottom right corner is obviously the tricky part. It's not just a simple bevel; it's slightly rounded.
The best solution I've come up with is to apply an SVG image mask to a pseudo element positioned to the right of the button and reduce the right padding to compensate. But this approach has its limitations:
it requires a fixed height button (at least, if I want maintain the aspect ratio of the corner)
it requires a different SVG for each button size
I don't see how it can work for the transparent button style
So I'm hoping someone can suggest a different/better approach!
Thanks
UPDATE:
Here is my current approach - https://codepen.io/peteheaney/pen/jwVEPm
$primary: #FAB500;
*, *::after, *::before {
font-family: sans-serif;
box-sizing: border-box;
}
.button {
background-image: none;
border-width: 2px;
border-style: solid;
border-color: transparent;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-bottom: 0;
text-align: center;
text-decoration: none;
text-transform: uppercase;
touch-action: manipulation;
vertical-align: middle;
white-space: nowrap;
transition: all 0.2s;
&:active,
&:hover,
&:focus {
text-decoration:none;
}
&--large {
font-size: 15px;
padding-left: 24.818px;
height: 52px;
line-height: 52px;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
position: relative;
margin-right: 24.818px;
&:after {
border-top: 2px solid $primary;
border-bottom: 2px solid $primary;
background: $primary;
content: "";
border-top-right-radius: 6px;
position: absolute;
left: 100%;
bottom: -2px;
width: 24.818px;
height: 52px;
mask: url(http://assets.peteheaney.com.s3.amazonaws.com/button-corner-right.svg) top left / cover;
}
}
&--primary {
color: #000;
background-color: $primary;
border-color: $primary;
&:active,
&:hover,
&:focus {
background-color: darken($primary, 2%);
border-color: darken($primary, 2%);
}
}
}
If you don't mind leaving the corner clickable, you could make the button invisible and just use a background image:
button{
width:x;
height:y;
border:none;
background-color:none
background-image:url(button_image.png);
background-position:center;
background-size:x y;
background-repeat:no-repeat;
}
With button_image.png being the image of your button style without text.
You can try to draw it like this using before and after :
.button {
position: relative;
display: inline-block;
background-color: orange;
color: white;
padding: 20px 40px;
font-size: 14px;
border-radius: 5px;
text-decoration: none;
}
.button:after {
content: '';
position: absolute;
z-index: 10;
display: block;
bottom: -6px;
right: -2px;
width: 10px;
height: 20px;
transform: rotate(45deg);
background-color: white;
}
.button:before {
content: '';
position: absolute;
z-index: 100;
display: block;
bottom: -1px;
right: 4px;
width: 13px;
height: 23px;
transform: rotate(45deg);
background-color: orange;
border-radius: 10px;
}
Button
Here is an example of how this could possibly be achieved with pure CSS.
However an image or an SVG might be a more efficient way to solve this issue.
.Large{
position:relative;
display:inline-block;
background:#FFB300;
border:none;
padding:20px 0 20px 30px;
border-radius:10px 0 0 10px;
height:40px;
font:700 1.5em/40px Arial;
}
.Large::after{
content:"";
display:block;
position:absolute;
top:0;
right:-30px;
width:30px;
height:50px;
background:#FFB300;
border-radius:0 10px 0 0;
}
.Large::before{
content:"";
display:block;
position:absolute;
bottom:0;
right:-30px;
width:0;
height:0;
border-top: 15px solid #FFB300;
border-right: 15px solid transparent;
border-bottom: 15px solid transparent;
border-left: 15px solid #FFB300;
}
<a class="Large">LARGE</a>
I am not really happy with my result, but here it goes just in case you can make it better.
The different color is just to make it easier to see what is what.
I have focused on solving the transparent one. Once you have it, solving the other is easier.
:root {
--width: 10px;
--width2: 14px;
}
.test {
position: relative;
margin: 20px;
width: 300px;
height: 150px;
position: absolute;
border: var(--width) solid transparent;
border-image: linear-gradient(to bottom right, orange 0%, orange 70%, transparent 70%);
border-image-slice: 1;
}
.test:before {
content: "";
position: absolute;
height: 25px;
width: 150px;
right: 29px;
bottom: -10px;
transform: skewX(-45deg);
border: solid 0px transparent;
border-bottom-color: red;
border-bottom-width: var(--width);
border-right-color: red;
border-right-width: var(--width2);
border-bottom-right-radius: 25px;
}
.test:after {
content: "";
position: absolute;
height: 50px;
width: 25px;
right: -10px;
bottom: 29px;
transform: skewY(-45deg);
border: solid 0px transparent;
border-bottom-color: red;
border-bottom-width: var(--width2);
border-right-color: red;
border-right-width: var(--width);
border-bottom-right-radius: 25px;
}
<div class="test"></div>
I decided to go for the approach I have demonstrated in this pen - https://codepen.io/peteheaney/pen/bRBOMq (compiled CSS version below)
*, *::after, *::before {
font-family: sans-serif;
box-sizing: border-box;
}
.button {
background-image: none;
border-style: solid;
border-top-width: 2px;
border-bottom-width: 2px;
border-left-width: 2px;
border-right-width: 0;
border-color: transparent;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-bottom: 0;
text-align: center;
text-decoration: none;
text-transform: uppercase;
touch-action: manipulation;
vertical-align: middle;
white-space: normal;
transition: all 0.2s;
}
.button:active, .button:hover, .button:focus {
text-decoration: none;
}
.button--large {
font-size: 15px;
padding: 16px 0 14px 21px;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
position: relative;
margin-right: 21px;
}
.button--large:before {
content: "";
position: absolute;
left: 100%;
top: -2px;
width: 21px;
height: calc(100% - 17px);
border-top-right-radius: 6px;
}
.button--large:after {
position: absolute;
left: 100%;
bottom: -2px;
width: 21px;
height: 21px;
transition: all 0.2s;
}
.button--primary {
color: #000;
background-color: #FAB500;
border-color: #FAB500;
}
.button--primary:before {
background-color: #FAB500;
transition: all 0.2s;
}
.button--primary:active:before, .button--primary:hover:before, .button--primary:focus:before {
background-color: #f0ae00;
border-color: #f0ae00;
}
.button--primary:after {
content: url(http://assets.peteheaney.com.s3.amazonaws.com/button-corner-primary-large.svg);
}
.button--primary:active, .button--primary:hover, .button--primary:focus {
background-color: #f0ae00;
border-color: #f0ae00;
}
.button--secondary {
color: #000;
border-color: #FAB500;
}
.button--secondary:before {
border: 2px solid #FAB500;
border-bottom: 0;
border-left: 0;
transition: all 0.2s;
}
.button--secondary:active:before, .button--secondary:hover:before, .button--secondary:focus:before {
background-color: #FAB500;
}
.button--secondary:after {
content: url(http://assets.peteheaney.com.s3.amazonaws.com/button-corner-secondary-large.svg);
}
.button--secondary:active, .button--secondary:hover, .button--secondary:focus {
background-color: #FAB500;
border-color: #FAB500;
}
<a class="button button--large button--primary" href="">My button</a>
<a class="button button--large button--secondary" href="">My other button</a>
Firstly, I divided the right-hand portion into top and bottom (using :before and :after). The top-right pseudo element just has a background color and a top right border radius. This way the top-right portion can have a flexible height, meaning the buttons don't need to have a fixed height. The bottom right pseudo element is essentially an SVG ( using content: url(/path/to/svg.svg) ). This pseudo element always has a fixed width and height, so it maintains its size and aspect ratio regardless of the width/height of the button.
The outline style button is just a variation on the other style, with more borders and less backgrounds.
The only downside to this approach is the need for a different SVG for each button style. But I'm happy with that compromise.
Another take on Arthur's approach.
If you create the bottom right image (the white corner and the yellow corner border) you are able to position this so it stays to the bottom right and you have the rest of the button to style yourself.
button {
background-image:url(corner.svg);
height: 20px;
padding: 5px;
border-radius: 5px;
background-color: yellow;
background-repeat: no-repeat;
background-position: bottom right;
}