I want the nav bar to be stack vertically and when I hover over the link I want the underline effect to go from the beginning of the word and end at the last letter but instead it start at the center and goes way past the end.
.col-1 ul li {
list-style: none;
display: block;
margin: 0 20px;
color: #e4c95e;
position: relative;
}
.col-1 ul li a {
text-decoration: none;
text-transform: uppercase;
}
.col-1 ul li::after {
content: '';
height: 3px;
width: 0;
background: #925e02;
position: absolute;
bottom: -10px;
transition: 0.5s;
}
.col-1 ul li:hover::after {
width: 20%;
}
<div >
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About Us</a></li>
<li><a href="#">Meet The Squad</a></li>
<li><a href="#">Services</a></li>
</ul>
</div>
CodePudding user response:
The underline is positioned absolutely but without any coordinates so its showing exactly where your :after is. I suggest giving it left:0
. In addition, if you want it to span the width of your a
rather than the width of the li
you should change it to a:after
(rather than li:after
) and set your a
as position:relative
. EG:
.col-1 ul li {
list-style: none;
display: block;
margin: 0 20px;
color: #e4c95e;
position: relative;
}
.col-1 ul li a {
text-decoration: none;
text-transform: uppercase;
position:relative;
}
.col-1 ul li a::after {
content: '';
height: 3px;
width: 0;
background: #925e02;
position: absolute;
left:0;
bottom: -10px;
transition: 0.5s;
}
.col-1 ul li a:hover::after {
width: 100%;
}
<div >
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About Us</a></li>
<li><a href="#">Meet The Squad</a></li>
<li><a href="#">Services</a></li>
</ul>
</div>
CodePudding user response:
One approach, with explanatory comments in the code:
.col-1 ul li {
list-style: none;
display: block;
margin: 0 20px;
color: #e4c95e;
}
/* because you want the transition/animation to
be relative to the size of the text so the
contents of the <a>, I'm applying the
position: relative to the <a> element instead
of the <li> parent (which has a larger size
and is independent of the <a>: */
.col-1 ul li a {
text-decoration: none;
text-transform: uppercase;
position: relative;
}
a::after {
content: '';
height: 3px;
width: 100%;
background: #925e02;
position: absolute;
/* positioning the element at the bottom-left of the <a> element: */
bottom: 0;
left: 0;
/* setting the scale of the element to zero on the horizontal/X axis,
and to 1 (unchanged) on the Y/vertical axis: */
scale: 0 1;
/* transitioning the scale property, over 0.5 seconds using the
ease-in-out timing function: */
transition: scale 0.5s ease-in-out;
/* moving the transform-origin from the center (default) to the
lower-left corner so the scaling transition starts there: */
transform-origin: bottom left;
}
a:hover::after {
/* here we set the new scale to be full-size on both axes: */
scale: 1 1;
}
<div >
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About Us</a></li>
<li><a href="#">Meet The Squad</a></li>
<li><a href="#">Services</a></li>
</ul>
</div>
It's worth adding that I'm not entirely a fan of that implementation, because I prefer to hover anywhere on the list and have the link be active. To address that – quite personal – issue I offer the below:
:root {
/* CSS custom properties to allow for theming/styling in one place: */
--underlineColor: #925e02;
--underlineHeight: 3px;
--underlineSpace-before: 0px;
--underlineSpace-after: 3px;
}
.col-1 ul li {
list-style: none;
display: block;
margin: 0 20px;
color: #e4c95e;
}
.col-1 ul li a {
display: block;
text-decoration: none;
text-transform: uppercase;
/* purely for the demo; this is not required: */
background-color: antiquewhite;
}
/* here we're styling the <span> descendant of the <a> element, the <span>
being the element that is sized according to the word it contains: */
a span {
/* we use inline-block to allow for paddings and margins to be easily set: */
display: inline-block;
/* we're now positioning the underline relative to this element, rather than
its parent <a>, so add position: relative here: */
position: relative;
/* here I'm adding padding to the bottom of the element, using the calc
function to work out how much might be required; this is calculated
by adding the space before the underline (--underlineSpace-before)
to the height of the underline (--underlineHeight): */
padding-bottom: calc(var(--underlineSpace-before) var(--underlineHeight));
/* the bottom-margin is set to the same value of the custom property
--underlineSpace-after, and serves to allow some white-space between
adjacent elements: */
margin-bottom: var(--underlineSpace-after);
}
/* styling the pseudo-element of the <span> within the <a>: */
a span::after {
content: '';
/* we set the height of the underline to be equal to the property-value of
the custom --underlineHeight property: */
height: var(--underlineHeight);
width: 100%;
/* setting the background to the value of the --underlineColor custom-property: */
background: var(--underlineColor);
position: absolute;
/* positioning the element at the bottom-left of the <a> element: */
bottom: 0;
left: 0;
/* setting the scale of the element to zero on the horizontal/X axis,
and to 1 (unchanged) on the Y/vertical axis: */
scale: 0 1;
/* transitioning the scale property, over 0.5 seconds using the
ease-in-out timing function: */
transition: scale 0.5s ease-in-out;
/* moving the transform-origin from the center (default) to the
lower-left corner so the scaling transition starts there: */
transform-origin: bottom left;
}
/* styling the span::after pseudo-element in response to a hover event being
triggerd on the parent <a> element: */
a:hover span::after {
/* here we set the new scale to be full-size on both axes: */
scale: 1 1;
}
<div >
<ul>
<li><a href="#"><span>Home</span></a></li>
<li><a href="#"><span>About Us</span></a></li>
<li><a href="#"><span>Meet The Squad</span></a></li>
<li><a href="#"><span>Services</span></a></li>
</ul>
</div>