CSS animation on the container instead of on the link - html

I have a CSS border animation on an HTML link. The animation sets on mouse hover and it automatically adjusts to the with of the link. Once the mouse is hover, border animations appear in pairs, left-right + top-down. When the animation is over the borders will form a square around the link.
It works fine until the link gets a line break and instead of one line I have a link with two lines. In that case the animation will form around the top line in the link and ignore the line break.
I have been trying and trying and I cannot figure out a way to make the animation go around the whole link instead of only around the first meaning. Can anyone help me out?
Code Pen: https://codepen.io/jo-o-figueiredo/pen/KKZOjWM
Thanks in advance!
div.caixa {
margin: 4em auto;
padding: 4em;
box-sizing: border-box;
text-align: center;
}
.sparkle {
max-width: 10em;
color: #5a4d1a;
margin: auto auto;
font-size: 25px;
line-height: 40px;
text-decoration: underline;
text-decoration-color: #b1d6b1;
text-underline-offset: 0.5em;
text-decoration-thickness: 3px;
font-weight: 500;
}
.sparkle:hover {
cursor: pointer;
text-decoration: none;
color: #1a1a1a;
}
.u-hover--sparkle {
box-sizing: border-box;
position: relative;
padding: 0.75em;
}
.u-hover--sparkle::before,
.u-hover--sparkle::after {
content: "";
box-sizing: border-box;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
transform-origin: center;
transition: transform .20s;
}
.u-hover--sparkle::before {
border-top: 1px solid #1a1a1a;
border-bottom: 1px solid #1a1a1a;
transform: scale3d(0, 1, 1);
}
.u-hover--sparkle::after {
border-left: 1px solid #1a1a1a;
border-right: 1px solid #1a1a1a;
transform: scale3d(1, 0, 1);
}
.u-hover--sparkle:hover::before,
.u-hover--sparkle:hover::after {
transform: scale3d(1, 1, 1);
transition: transform .35s;
}
<div class="wpb_text_column wpb_content_element caixa">
<div class="wpb_wrapper">
<p>
<a class="sparkle u-hover--sparkle" href="#paket" rel="noopener">Sällskap -
Sammankomster</a>
</p>
</div>
</div>

Set the .sparkle to display block so it covers the whole thing.
Also define how your text should break, because if it's a long word, it has no choice to go out of bound by default.
.sparkle {
display: block;
word-break: break-all;
/* rest of your code */
}
div.caixa {
margin: 4em auto;
padding: 4em;
box-sizing: border-box;
text-align: center;
}
.sparkle {
max-width: 10em;
color: #5a4d1a;
margin: auto auto;
font-size: 25px;
line-height: 40px;
text-decoration: underline;
text-decoration-color: #b1d6b1;
text-underline-offset: 0.5em;
text-decoration-thickness: 3px;
font-weight: 500;
display: block;
word-break: break-word;
}
.sparkle:hover {
cursor: pointer;
text-decoration: none;
color: #1a1a1a;
}
.u-hover--sparkle {
box-sizing: border-box;
position: relative;
padding: 0.75em;
}
.u-hover--sparkle::before,
.u-hover--sparkle::after {
content: "";
box-sizing: border-box;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
transform-origin: center;
transition: transform .20s;
}
.u-hover--sparkle::before {
border-top: 1px solid #1a1a1a;
border-bottom: 1px solid #1a1a1a;
transform: scale3d(0, 1, 1);
}
.u-hover--sparkle::after {
border-left: 1px solid #1a1a1a;
border-right: 1px solid #1a1a1a;
transform: scale3d(1, 0, 1);
}
.u-hover--sparkle:hover::before,
.u-hover--sparkle:hover::after {
transform: scale3d(1, 1, 1);
transition: transform .35s;
}
<div class="wpb_text_column wpb_content_element caixa">
<a class="sparkle u-hover--sparkle" href="#paket" rel="noopener">Sällskap -
Sammankomster</a>
</div>

I think there are multiple things to point out:
Easy Fix: Add display: block; to the .sparkle class and increase max-width to enable the text to stand in one line.
Alternatively you could also apply the animation styles to the divs surrounding the Link
Optional: I think you could also remove the <p> element surrounding the link as it is unnecessarily making your markup more complex.

Related

Element appearing with :focus-visible

In my project I have a list of 'result items' which can be favourited and then they appear on in a favourites column to the side of the page.
To allow keyboard users easy access, I have created a hidden cta which allows them to skip directly to their favourited item, without having to tab through all the result items first.
I only want this cta to be visible when it is tabbed to. My understanding is that :focus-visible would enable this. However, for some reason, it's not working for me. My HTML and CSS look like:
.sr-only-focusable {
position: absolute;
visibility: hidden;
left: 56%;
top: rem(65);
border-radius: 5px;
border: 1px solid #d7d7d7;
background-color: $white;
padding: 1rem 2rem;
z-index: 10;
}
.sr-only-focusable:focus-visible {
visibility: visible;
}
<div class="sr-only-focusable">
<button tabindex="0" #click="skipToShortlist">Skip To Shortlist</button>
</div>
Could anyone help me figure out where i'm going wrong?
Thanks in advance
The button element is what you're trying to tab to, not the div it's contained in. Rather than trying to get to the div, target the button instead. Also, use opacity because visibility doesn't seem to play nicely with tabindex. You can also apply your styling to the button as well.
.sr-only-focusable {
position: absolute;
left: 56%;
top: rem(65);
z-index: 10;
}
.myBtn {
display: inline-block;
font-family: Helvetica, Arial, sans-serif;
color: black;
margin: 0 auto;
font-size: 1.2vw;
font-weight: 700;
line-height: 1.25;
letter-spacing: 0.5px;
cursor: pointer;
text-decoration: none;
opacity: 0;
border-radius: 5px;
border: 1px solid #d7d7d7;
background-color: $white;
padding: 1rem 2rem;
}
.myBtn:focus-visible {
opacity: 1;
}
<div class="sr-only-focusable">
<button class="myBtn" tabindex="0" #click="skipToShortlist">Skip To Shortlist</button>
</div>
From my experience (mostly on chrome) elements with display:none or visibility:hidden cannot be focused by mouse or by keyboard.
Most implementations use something along the lines of this:
.wrapper {
background: black;
text-align: center;
width: 360px;
height: 100px;
padding: 40px;
box-sizing: border-box;
color: blanchedalmond;
}
.image-nav-button {
color: blanchedalmond;
text-decoration: none;
font-size: 20px;
line-height: 1em;
width:1px;
height:1px;
position:absolute;
clip: rect(1px,1px,1px,1px);
clip-path: inset(50%);
}
.next {
float: right;
}
.prev {
float: left;
}
.image-nav-button:focus {
outline: none;
/* Try uncommenting below, then clicking the buttons */
/* outline: 3px solid red; */
}
.image-nav-button:focus-visible {
outline: 3px solid blanchedalmond;
width:auto;
height:auto;
position:relative;
clip: none;
clip-path: none;
}
<div class="wrapper">
← Prev Image
Next Image →
</div>

How to make ::after content have the same width an height as the previous?

I want to make a small button hover animation. the animation is like that:
a blue div which have the same width an height as the button comes from the bottom left of the button to cover it. The problem is that they have not the same height and width.
Here's the HTML and the css :
[![button{
box-sizing: border-box;
background-color: transparent;
border: none;
display: inline-block;
}
.button-wrapper {
position: relative;
overflow: hidden;
padding: 15px 30px;
font-family: 'Montserrat', sans-serif;
font-weight: bold;
font-size: 14px;
line-height: 20px;
border: solid 2px #2A5A8B;
border-radius: 6px;
text-decoration: none;
color: #2A5A8B;
cursor : pointer;
transition: all .5s;
z-index: 1;
}
.button-wrapper::after{
width: 100%;
height: 100%;
margin: auto;
position: absolute;
bottom: -100%;
right: -100%;
background-color: #2A5A8B;
transition: all .25s;
z-index: -1;
content: '';
}
.button-wrapper:hover{
color: white;
}
.button-wrapper:hover::after{
transform: translateX(-100%) translateY(-100%);
}
<button>
<div className='button-wrapper'>
{Login}
</div>
</button>
PS: it's working properly on firefox.

Transforming and tranisitions in CSS | Transition not working

I have the following css file
body {
font-family: Baskerville;
background: #ecf0f1;
color: #2c3e50;
}
h1 {
margin: 16px 0;
padding-left: 16px;
border-left: 5px solid #e74c3c;
font-family: Baskerville;
font-size: 48px;
}
h3 {
margin: 16px 0;
padding-left: 16px;
color: #cccac4;
}
.container1 {
padding: center;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
}
.container1 .checkbox {
padding: 8px 48px;
margin: 8px;
font-family: Baskerville;
font-size: 25px;
}
input[type="checkbox"]{
display: none;
}
label {
position: relative;
}
label::before {
content: "";
background: url("check-circle.svg");
background-position: center;
background-size: contain;
width: 32px;
height: 32px;
position: absolute;
left: -44px;
top: -8px;
transform: scale(0) rotateZ(180deg);
transition: all 0.4s cubic-bezier(0.54, 0.01, 0, 1.49);
}
input[type="checkbox"]:checked + label::before {
transform: scale(1.0) rotateZ(0deg);
}
label::after {
content: "";
border: 2px solid #27ae60;
width: 24px;
height: 24px;
position: absolute;
left: -42px;
top: 1px;
border-radius: 50%;
}
This is a simple transform and transition where i rotate the img (check-circle.svg) in those 4 curve points of cubic-bezier , whenever it is checked or unchecked after. However the transition and transformation wont work. It will simply not show. Where am i mistaken ?
Are you sure you've placed <label>...</label> immediately after <input type="checkbox"/>? Code seems fine, although I'm not sure what is the purpose of input[type="checkbox"]{ display: none; }. Posting html would be nice too.
Also you can check if provided svg's url is correct. Try to replace it with some other svg url found on internet.
make sure that (label) is a direct next child of (input)

How to keep components auto resizable while creating templates in React JS?

So I am trying to put a background image and then center the text to it, but when I change the screen size the text misaligns and moves to the top.
Here's my code:
import React from "react";
import UniversalValues from "../constants.js";
export default function Body() {
return (
<div>
<div className="Container">
<img
className="ResizeImage"
src="https://images.unsplash.com/photo-1533139143976-30918502365b?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max"
alt="Background not loading! X_X"
/>
<div className="TextField">
<h1 className="BGH1">WE DO IT TOGETHER</h1>
<h1 className="BGH1">SO LET'S CREATE</h1>
</div>
</div>
</div>
);
}
Here is my css file:
.App {
font-family: sans-serif;
text-align: center;
}
.BGH1 {
letter-spacing: 0.06em;
font-family: "Cinzel", serif;
font-size: 5rem;
position: relative;
}
.BrandPoint {
font-size: 3rem;
font-family: "Cinzel", serif;
padding-left: 3rem;
}
.Container {
position: relative;
}
.dropbtn {
background: transparent;
color: white;
padding-bottom: 10px;
font-size: 1.2rem;
font-weight: bold;
border: none;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #33393f;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: white;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.dropdown-content a:hover {
transition: transform 0.5s ease;
transform: scale(0.9);
color: #3eccb5;
border: 1px solid;
border-radius: 0.2rem;
border-color: #e0dede;
}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown:hover .dropbtn {
transition: transform 0.5s ease;
transform: scale(0.9);
color: #3eccb5;
border: 1px solid;
border-radius: 0.2rem;
border-color: #e0dede;
}
.HeaderElem {
color: white;
padding-bottom: 10px;
font-size: 1.2rem;
}
.HeaderElem:hover {
transition: transform 0.5s ease;
transform: scale(0.9);
color: #3eccb5;
border: 1px solid;
border-radius: 0.2rem;
border-color: #e0dede;
}
.HeaderSeperator {
padding-left: 2rem;
}
.HeadUp {
position: fixed;
top: 0;
left: 0;
}
.ResizeImage {
height: auto;
width: 100%;
margin: 0;
padding: 0;
opacity: 0.99;
}
.TextField {
position: absolute;
bottom: 40%;
left: 35%;
color: white;
padding-left: 20px;
padding-right: 20px;
}
What I am getting vs What I wanted:
I want to pack this whole thing together and so it could just effectively change its shape according to the screen size. I have used Bootstrap but I am new to React and designing my entire website on codesandbox.io. Do let me know the best way to do so.
Thanks in advance.
I think your problem is purely HTML/CSS and not so much React. Thanks for flexbox centering content got a lot easier today.
Change your HTML like this:
<div>
<div class="Container">
<div class="imageContainer"></div>
<div class="TextField">
<h1 class="BGH1">WE DO IT TOGETHER</h1>
<h1 class="BGH1">SO LET'S CREATE</h1>
</div>
</div>
</div>
And your CSS like this:
.Container {
display: flex;
justify-content: center;
align-items: center;
background-color:blue;
position: relative;
color: white;
text-align: center;
height: 300px;
}
.imageContainer {
position: absolute;
width: 100%;
height: 100%;
opacity: 0.2;
background-image: url("https://images.unsplash.com/photo-1533139143976-30918502365b?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max");
background-position: center center;
}
Here is a fiddle test it: https://jsfiddle.net/gtqna9c1/7/
How it works
Instead of trying to center changing text by absolute positioning it is a lot easier to create conditions where the text is always centered, no matter what. The background image is now a simple background of a div that is covering your whole box.
The fiddle is simplified and coloured for clarity. Feel free to add paddings etc. as you wish.

Best way to use a right pointing arrow in CSS animation

I'm trying to create a continue button that shows a right pointing arrow in a hover state. I also want the arrow to be centered.
I've tried adding .icon-arrow-right:before {content: "&rarr";}
body {
background: #00b894;
}
.btn {
font-size: 14px;
background: none;
padding: 25px 80px;
display: inline-block;
margin: 15px 30px;
position: relative;
border: 3px solid #fff;
color: #fff;
overflow: hidden;
transition: all 0.3s;
}
.btn:before {
position: absolute;
height: 100%;
font-size: 125%;
line-height: 3.5;
color: #fff;
transition: all 0.3s;
left: 130%;
top: 0;
}
.icon-arrow-right:before {
content: "#";
}
.btn:hover:before {
left: 80%;
}
<button class="btn icon-arrow-right">Continue</button>
I would like the arrow to be to the right of the button text in a hover state. I would also like the arrow to be centered with the button text.
Make your pseudo element into the triangle you desire:
.icon-arrow-right:before {
margin-top: 21px;
content: "";
width: 0;
height: 0;
border-top: 7px solid transparent;
border-left: 14px solid white;
border-bottom: 7px solid transparent;
}
This uses the awesome transparent border trick to make the element box appear as a triangle. Change the border widths to alter the size of the triangle, notice the border with color is twice as wide as the transparent sides. You can play with these values to nuance the triangle how you like.
I also changed how you are positioning the text in the button:
.btn {
padding: 0 80px; /* padding on sides only */
height: 64px; /* height of the button you want */
line-height: 58px; /* same as height minus the border-top and border-bottom */
border: 3px solid #fff;
}
By using line-height this way you can guarantee your text will be vertically centered in the button at any font-size.
Check out the full working example:
body {
background: #00b894;
}
.btn {
font-size: 14px;
background: none;
padding: 0 80px; /* padding on sides only */
height: 64px; /* height of the button you want */
line-height: 58px; /* same as height minus the border-top and border-bottom */
display: inline-block;
margin: 15px 30px;
position: relative;
border: 3px solid #fff;
color: #fff;
overflow: hidden;
transition: all 0.3s;
cursor: pointer;
}
.btn:before {
position: absolute;
height: 100%;
font-size: 125%;
line-height: 3.5;
color: #fff;
transition: all 0.3s;
left: 130%;
top: 0;
}
.icon-arrow-right:before {
margin-top: 21px;
content: "";
width: 0;
height: 0;
border-top: 7px solid transparent;
border-left: 14px solid white;
border-bottom: 7px solid transparent;
}
.btn:hover:before {
left: 80%;
}
<button class="btn icon-arrow-right">Continue</button>
I have vertically centered the arrow with top:50%;transform:translateY(-50%);. I removed the line-height and height CSS from the .btn pseudo element because they weren't needed. I have just used > for the arrow, but you can use something like fontawesome to get a nice icon.
body {
background: #00b894;
}
.btn {
font-size: 14px;
background: none;
padding: 25px 80px;
display: inline-block;
margin: 15px 30px;
position: relative;
border: 3px solid #fff;
color: #fff;
overflow: hidden;
transition: all 0.3s;
}
.btn:before {
position: absolute;
font-size: 125%;
color: #fff;
transition: all 0.3s;
left: 130%;
top:50%;
transform:translateY(-50%);
}
.icon-arrow-right:before {
content: ">";
}
.btn:hover:before {
left: 80%;
}
<button class="btn icon-arrow-right">Continue</button>
Just expanding on #BugsArePeopleToo 's answer, using borders ans transforms to keep the ">" shape the OP wanted.
body {
background: #00b894;
}
.btn {
font-size: 14px;
background: none;
padding: 0 80px; /* padding on sides only */
height: 64px; /* height of the button you want */
line-height: 58px; /* same as height minus the border-top and border-bottom */
display: inline-block;
margin: 15px 30px;
position: relative;
border: 3px solid #fff;
color: #fff;
overflow: hidden;
transition: all 0.3s;
cursor: pointer;
}
.btn:before {
position: absolute;
height: 100%;
font-size: 125%;
line-height: 3.5;
color: #fff;
transition: all 0.3s;
left: 130%;
top: 0;
}
.icon-arrow-right:before {
content: "";
width: 0.5em;
height: 0.5em;
position:absolute;
top:50%;
border-top:2px solid #fff;
border-right:2px solid #fff;
transform:translateY(-50%) rotate(45deg);
}
.btn:hover:before {
left: 80%;
}
<button class="btn icon-arrow-right">Continue</button>