I'm working with React js and I have created a nav where lines animate from 0% to 100% under items on hover and the last item that was clicked gets assigned the .current
class. The item with class .current
should not animate but should maintain the line at 100% width. I had this working previously but I added CSS that moves the text in <li>
's on hover and it broke.
Snippet:
html,
body {
padding: 0;
margin: 0;
font-family: "sequel-sans-roman", -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
.container {
padding: 0 2rem;
}
.main {
min-height: 100vh;
padding: 4rem 0;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
a {
color: inherit;
text-decoration: none;
}
* {
box-sizing: border-box;
}
.navIcon {
display: inline-block;
flex-grow: 1;
}
.nav {
display: flex;
justify-content: space-between;
width: 100%;
margin-top: 2.4em;
/* coordinates w height of line away from link, MUST BE = */
}
.snip1168 {
text-align: center;
text-transform: uppercase;
}
.snip1168 * {
box-sizing: border-box;
}
.snip1168 li {
display: inline-block;
list-style: outside none none;
margin: 0 1.5em;
padding: 0;
background: ppink;
}
.snip1168 li {
padding: 2.4em 0 0.5em;
/* height of line away from link */
color: rgba(0, 0, 0, 1);
position: relative;
text-decoration: none;
background: pink;
display: inline-block;
}
.snip1168 li:before,
.snip1168 li:after {
position: absolute;
-webkit-transition: all 0.35s ease;
transition: all 0.35s ease;
}
.snip1168 li:before {
top: 0;
display: inline-block;
height: 3px;
width: 0%;
content: "";
background-color: black;
}
.snip1168 li:hover:before,
.snip1168 .current a:before {
opacity: 1;
width: 100%;
}
.snip1168 li:hover:after,
.snip1168 .current li:after {
max-width: 100%;
}
.mainText {
text-transform: uppercase;
font-size: 1.1rem;
}
.snip1168 li a {
transition: transform ease 400ms;
transform: translate(0, 0);
display: inline-block;
}
.snip1168 li:hover a {
transition: transform ease 400ms;
transform: translate(0, -10px);
}
<div class='container'>
<main class='main'>
<div class='nav'>
<div class='navIcon'>
<img src="https://picsum.photos/40" height={40} width={40} />
</div>
<ul class='snip1168'>
<li class='current'><a href="#" data-hover="Work">Work</a></li>
<li><a href="#" data-hover="Recs">Recs</a></li>
<li><a href="#" data-hover="Say Hi">Say Hi</a></li>
</ul>
</div>
</main>
</div>
I have tried doing something like this but it has no effect:
.snip1168 .current a {
width: 100%;
}
How can I keep the lines at 100% width on .current
?
CodePudding user response:
In the above code, you have used to show the clicked nav item, however, a good approach is to use id="current" instead (because there always will be a single item which is active/clicked/current) and add a new CSS rule like below.
li#current::before{
width:100% !important;
}
html,
body {
padding: 0;
margin: 0;
font-family: "sequel-sans-roman", -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
.container {
padding: 0 2rem;
}
.main {
min-height: 100vh;
padding: 4rem 0;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
a {
color: inherit;
text-decoration: none;
}
* {
box-sizing: border-box;
}
.navIcon {
display: inline-block;
flex-grow: 1;
}
.nav {
display: flex;
justify-content: space-between;
width: 100%;
margin-top: 2.4em;
/* coordinates w height of line away from link, MUST BE = */
}
.snip1168 {
text-align: center;
text-transform: uppercase;
}
.snip1168 * {
box-sizing: border-box;
}
.snip1168 li {
display: inline-block;
list-style: outside none none;
margin: 0 1.5em;
padding: 0;
background: ppink;
}
.snip1168 li {
padding: 2.4em 0 0.5em;
/* height of line away from link */
color: rgba(0, 0, 0, 1);
position: relative;
text-decoration: none;
background: pink;
display: inline-block;
}
.snip1168 li:before,
.snip1168 li:after {
position: absolute;
-webkit-transition: all 0.35s ease;
transition: all 0.35s ease;
}
.snip1168 li:before {
top: 0;
display: inline-block;
height: 3px;
width: 0%;
content: "";
background-color: black;
}
.snip1168 li:hover:before,
.snip1168 .current a:before {
opacity: 1; /*not needed*/
width: 100%;
}
/*Added Code*/
li#current::before{
width:100% !important;
}
.snip1168 li:hover:after,
.snip1168 .current li:after {
max-width: 100%;
}
.mainText {
text-transform: uppercase;
font-size: 1.1rem;
}
.snip1168 li a {
transition: transform ease 400ms;
transform: translate(0, 0);
display: inline-block;
}
<div class='container'>
<main class='main'>
<div class='nav'>
<div class='navIcon'>
<img src="https://picsum.photos/40" height={40} width={40} />
</div>
<ul class='snip1168'>
<li id='current'><a href="#" data-hover="Work">Work</a></li>
<li ><a href="#" data-hover="Recs">Recs</a></li>
<li><a href="#" data-hover="Say Hi">Say Hi</a></li>
</ul>
</div>
</main>
</div>
Working example : Codepen
CodePudding user response:
If I understood correctly you want the line that animates to stay visible aka 100% width when the .current is applied.
I believe Im seeing couple of mistakes especially with your selectors but to prevent breaking your existing code, adding this should fix it.
ul li.current::before {
width: 100%;
}