My Link in react won't work when clicked on - css

When i click on the links, they wont work. But when I change the position in ul.pullRight li:before to relative, the styling disappears and the link works. There's a hover effect in the links.
This is my NavBar component
import React from 'react'
import PropTypes from 'prop-types'
import { Link } from 'react-router-dom'
const Navbar = ({ icon, title }) => {
return (
<nav className='navbar bg-primary'>
<h1 style={{ fontWeight: 'bold', fontSize: '35px', color: 'whitesmoke'}}><i className={icon}></i>{title}</h1>
<ul className='container pullRight'>
{/* LINK to is used in place of <a> tag */}
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/login">Login</Link></li>
<li><Link to="/logout">LogOut</Link></li>
</ul>
</nav>
)
}
This is the css file
/* Pull right */
ul.container li
{
color: #FFF;
text-decoration: none;
font: 15px Raleway;
margin: 0px 10px;
padding: 10px 10px;
position: relative;
z-index: 0;
cursor: pointer;
}
ul.pullRight li:before
{
position: absolute;
width: 2px;
height: 100%;
left: 0px;
top: 0px;
content: '';
background: #FFF;
opacity: 0.3;
transition: all 0.3s;
}
ul.pullRight li:hover:before
{
width: 100%;
}

here i'm assuming that you don't want to li:before to be clicked so you can add this to the css, pointer-events: none and it won't cover the initial element anymore.
i did not test this, but please do test and tell if it worked.

Related

How to change hamburger back to original state after clicking on mobile link from the expanded mobile menu?

I have figured out how to close the expanded mobile menu after a mobile link is clicked, but can't figure out how to return the hamburger icon back to the bars. I'm using the npm package hamburger-react.
Here's the component:
import React, { useState } from "react";
import "./Navbar.css";
import { Fade as Hamburger } from "hamburger-react";
const Navbar = () => {
window.addEventListener("scroll", function () {
const header = document.querySelector(".header");
header.classList.toggle("active", window.scrollY > 0);
});
window.addEventListener("scroll", function () {
const hamburger = document.querySelector(".hamburger");
hamburger.classList.toggle("active", window.scrollY > 0);
});
const [click, setClick] = useState(false);
const handleClick = () => setClick(!click);
const closeMenu = () => setClick(false);
return (
<div className="parent">
<div className="header d__flex justify__content__flex__end pxy__30">
<ul className={click ? "nav-menu active" : "nav-menu"}>
<li className="nav__items mx__15">
<a href="/" onClick={closeMenu}>
Home
</a>
</li>
<li className="nav__items mx__15">
<a href="#about" onClick={closeMenu}>
About
</a>
</li>
<li className="nav__items mx__15">
<a href="#projects" onClick={closeMenu}>
Projects
</a>
</li>
<li className="nav__items mx__15">
<a href="#contact" onClick={closeMenu}>
Contact
</a>
</li>
</ul>
<Hamburger
className="hamburger-react"
color="white"
direction="right"
rounded
onToggle={handleClick}
/>
</div>
</div>
);
};
export default Navbar;
Here's the css:
.parent {
height: 124px;
}
img {
padding-top: 5px;
}
.nav__items {
font-size: 18px;
}
.nav-menu {
display: flex;
text-transform: uppercase;
letter-spacing: 1px;
}
.nav-link {
color: #fff;
}
ul a {
display: inline-block;
position: relative;
padding: 1.5em 0;
}
ul a:hover {
color: #f9004d;
}
ul a::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 0.2em;
background-color: #f9004d;
opacity: 0;
transition: opacity 300ms, transform 300ms;
}
ul a:hover::after,
ul a:focus::after {
opacity: 1;
transform: translate3d(0, 0.2em, 0);
}
/* Scale from center */
ul a::after {
opacity: 1;
transform: scale(0);
transform-origin: center;
}
ul a:hover::after,
ul a:focus::after {
transform: scale(1);
}
.hamburger-react {
display: none;
position: fixed;
/* top: 3.2rem; */
top: 1rem;
right: 2rem;
transition: 0.4s all ease;
cursor: pointer;
}
.hamburger-react.active {
position: fixed;
/* z-index: 1000; */
top: 1.5rem;
right: 2rem;
}
.header {
transition: 0.4s all ease;
}
.header.active {
position: fixed;
z-index: 1;
width: 100%;
padding: 0px 30px;
background-color: #010101;
}
#media only screen and (max-width: 960px) {
.hamburger-react {
display: block;
z-index: 2;
}
.nav-menu {
position: fixed;
right: -100%;
flex-direction: column;
justify-content: center;
background-color: #010101;
width: 100%;
height: 100%;
text-align: center;
transition: 0.4s;
top: 0%;
}
.nav-menu.active {
right: 0;
z-index: 1;
}
.nav__items {
font-size: 1.5rem;
}
}
I feel like I need to add some more functionality to the closeMenu function that would return the hamburger back to bars, but haven't been successful.
Assuming that the goal is to change the hamburger icon back to the inactive look when closeMenu fires, try set toggled={click} as a prop for Hamburger.
It seems that the click state is intended to control the icon, and its handler events are all set, so Hamburger should just need to set it for toggled to get controlled.
<Hamburger
className="hamburger-react"
color="white"
direction="right"
rounded
// 👇 Pass the state to control the component
toggled={click}
onToggle={handleClick}
/>

When using a media query, target tag does not disappear

Hi I think this is very simple question so I apologize in advance for not being able to resolve it myself. I'm trying to make tag disappear by media query when width of window becomes less than 1200px. But it doesn't disappear. I think it's a matter of inheritance. I'd appreciate if you let me know how to solve this.
this is NaviSearch.jsx file. I want to make top tag disappear
import React from "react";
import "../navi.css";
import pencil from "./images/pencil.png";
import { Link } from "react-router-dom";
function NaviRecent (props) {
return (
<Link to="/login" style={{textDecoration : 'none'}}>
<button id="NaviRecent">
<img src={pencil} id="NaviRecentImage"/>
<span id="NaviRecentText">최근강의</span>
</button>
</Link>
);
}
export default NaviRecent;
and this file is css file. I only brought what seemed relevant
#Navi {
position: sticky;
background-color: #fff;
width: 100%;
height: 64px;
top: -1px;
z-index: 5;
box-shadow: 0 2px 4px 0 hsl(0deg 0% 81% / 50%);
width: 1263.330;
height: 64px;
display: flex;
align-items: center;
justify-content: space-between;
}
#NaviRecent {
border: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
position: relative;
right: 20px;
width: 100px;
height: 30px;
padding: 8px;
background: #00c471;
color: #fff;
border-radius: 4px;
}
#NaviHiddenLogo {
display: none;
}
#NaviRecentText {
box-sizing: border-box;
color: white;
cursor: pointer;
font-family: Pretendard,-apple-system,BlinkMacSystemFont,system-ui,Roboto,Helvetica Neue,Segoe UI,Apple SD Gothic Neo,Noto Sans KR,Malgun Gothic,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,sans-serif;
font-size: 16px;
font-weight: 600;
margin-left: 4px;
}
#NaviRecentImage {
width: 15px;
height: 15px;
}
#media screen and (max-width: 1020px) {
#NaviRecent {
display: none;
}
}
you should wrap into a tag like this :
import React from "react";
import "../navi.css";
import pencil from "./images/pencil.png";
import { BrowserRouter as Router, Link } from "react-router-dom";
function NaviRecent(props) {
return (
<Router>
<Link to="/login" style={{ textDecoration: "none" }}>
<button id="NaviRecent">
<img src={pencil} id="NaviRecentImage"/>
<span id="NaviRecentText">최근강의</span>
</button>
</Link>
</Router>
);
}
export default NaviRecent;
Be carefull, in your css file max-width is 1020px and not 1200px as you mentioned in your statement.
Hope it will help.

How to display a fixed navbar in Nextjs?

I have a Nextjs app that displays the same navbar on each page. The navbar has a fixed position. The display is correct on the homepage (written in index.tsx). But when I click on a new page, the new page is hidden behind the navbar!
The issue disappears if I remove the fixed position property. But I can't believe Nextjs doesn't support such a basic task.
The code is very simple:
// _app.tsx
function MyApp({ Component, pageProps }: AppProps) {
return (
<>
<Navbar />
<Component {...pageProps} />
</>
);
}
export default MyApp;
// about.tsx
const About: NextPage = () => {
return (
<section>
<h1>About</h1>
</section>
);
};
export default About
// navbar.tsx
export default function Navbar() {
const router = useRouter();
return (
<nav className={styles.navbar}>
<Link href="/">
<Image
src={icon.src}
className={styles.logo}
alt="logo"
width={70}
height={70}
/>
</Link>
<ul className={styles.list}>
<li
className={
router.route === "/about" ? styles.listItemActive : styles.listItem
}
>
<Link href="/about">About</Link>
</li>
</ul>
</nav>
);
}
//navbar.module.css
.navbar {
background-color: var(--dark);
color: #fff;
height: 80px;
width: 100vw;
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px;
position: fixed;
z-index: 999;
}
.logo {
cursor: pointer;
}
.list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
align-items: center;
}
.listItem {
cursor: pointer;
}
.listItemActive {
cursor: pointer;
color: var(--red);
}
How to fix this?
Just add a position to your css.
top: 0px;
right: 0px;
left: 0px;
https://developer.mozilla.org/docs/Web/CSS/position
If what you want is to have a sticky navbar, you can do it with pure CSS with position: sticky like this:
header, nav, main {
padding: 1.7rem 1rem;
}
header {
background-color: #d99;
}
nav {
position: sticky;
top: 2rem;
background-color: #9d9;
}
main {
height: 100vh;
background-color: #99d;
}
--
<header>
Header
</header>
<nav>
Navbar
</nav>
<main>
Main
</main>
position: sticky;
top: 0px;
right: 0px;
left: 0px;
this worked for me!

Hover effect not being applied to SVG Nested in NavLink

How do I get the nested SVG to have the same hover effect as the anchor tag? When I hover over one it should change both, but right now they are not being seen as the same entity.
I am trying to apply a style to an SVG on hover. The SVG is nested inside of a NavLink component. The CSS that is class-specific gets applied to the SVG, but the hover for the a tag that the SVG is nested in only applies to the a tag's text. I have tried using just the Link component from react-router-dom. I have noticed that when I removed the text-decoration: none from my CSS, the underline only applies to the text. In the rendered HTML the a tag DOES nest the svg tag.
I have tried wrapping the anchor tag and SVG in a span and giving the span the hover effect, it did not work.
component
import {Link, NavLink} from "react-router-dom";
import logo from '../../assets/LogoOnly_Square_Transparent.png';
import { ReactComponent as CalculatorIcon } from '../../assets/calculator.svg';
import './header.styles.scss';
export const Header = () => {
return (
<nav className="header">
<div className='options'>
<Link className='logo-container' to='/'>
<img src={logo} alt="Logo" className='logo'/>
</Link>
<NavLink to='/calculator' className='header-option'>CALCULATOR<CalculatorIcon className='link-icon'/></NavLink>
</div>
<div className='options-right'>
<Link to='/sign-in-sign-up' className='header-option'>SIGN IN</Link>
</div>
</nav>
)
}
CSS
border-bottom: 1px solid #D1D3D4;
height: 70px;
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 25px;
padding: 5px;
.options {
height: 100%;
display: flex;
align-items: center;
justify-content: flex-start;
.logo-container {
width: 70px;
margin: 5px 0;
height: 100%;
.logo {
height: 100%;
}
}
.header-option {
padding: 10px 15px;
font-size: 16px;
.link-icon {
height: 13px;
fill: #58595B;
margin: auto 5px;
}
&:hover {
color: #4FB47C;
fill: #4FB47C;
}
}
}
a {
text-decoration: none;
color: #58595B;
&:hover {
color: #4FB47C;
fill: #4FB47C;
}
}
.options-right {
height: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
.header-option {
padding: 10px 15px;
}
}
}

I need to toggle between an X button and hamburger menu with Bootstrap. I'm using React.js

I'm using the latest version of Bootstrap and want to toggle between the famous X icon and hamburger menu. I don't know if I can actually change the 3 lines of the menu since it's by default, but these 2 icons presently overlap each other.
So there are 2 questions here:
How can I toggle these two icons?
When the menu is clicked, it should have a complete white background (right now it doesn't completely cover the screen in white)
Sorry I don't have a sandbox example for you right now.
Thanks for your input!
/*JSX code*/
import React from 'react';
import { NavigationBarStyled } from './style';
import { Nav, Navbar } from 'react-bootstrap';
//IMAGES
import logo from '../../images/adyslogo.png';
import Image from 'react-bootstrap/Image';
import { GrCart } from 'react-icons/gr';
import CloseButton from '../../images/closebutton.svg';
const NavigationBar = () => {
return (
<NavigationBarStyled>
<Navbar expand='sm' fixed='top'>
<Navbar.Brand href='/'><Image src={logo} className='logo'/></Navbar.Brand>
<div className='close-button'>
<button type="button" className="x-closebutton" aria-label="Close">
<img src={CloseButton} className='x-button' alt="close configuration" draggable="false" />
</button>
<Navbar.Toggle aria-controls='basic-navbar-nav' className='hamburger-menu'/>
</div>
<Navbar.Collapse id='basic-navbar-nav'>
<Nav className='mr-auto'>
<Nav.Item><Nav.Link href='/' className="middle-menu">HOME</Nav.Link></Nav.Item>
<Nav.Item><Nav.Link href='/about' className="middle-menu">ABOUT</Nav.Link></Nav.Item>
<Nav.Item><Nav.Link href='/menu' className="middle-menu">MENU</Nav.Link></Nav.Item>
<Nav.Item><Nav.Link href='/gallery' className="middle-menu">GALLERY</Nav.Link></Nav.Item>
<Nav.Item><Nav.Link href='/contact' className="middle-menu">CONTACT</Nav.Link></Nav.Item>
</Nav>
<Nav className='ml-auto'>
<Nav.Item><Nav.Link href='/cart'><GrCart size='25px' className='cart'/></Nav.Link></Nav.Item>
</Nav>
</Navbar.Collapse>
</Navbar>
</NavigationBarStyled>
)
}
export default NavigationBar;
/*CSS*/
import styled from 'styled-components';
export const NavigationBarStyled = styled.nav`
.navbar {
background-color: #FFF;
height: 80px;
}
.navbar-brand, .navbar-nav .nav-link {
color: #273746 ;
font-size: 1rem;
font-weight: 600;
&:hover {
color: rgb(255, 20, 147);
}
}
.logo {
max-height: 60px;
max-width: 60px;
}
.middle-menu {
margin: 20px;
}
.cart {
margin-right: 50px;
}
.close-button {
display: flex;
align-items: flex-start;
justify-content: flex-start;
}
.x-closebutton {
display: flex;
align-items: flex-start;
justify-content: flex-start;
border: none;
background-color: #fff;
margin-right: -54px;
}
.x-button {
display: flex;
width: 45px;
height: 45px;
cursor: pointer;
}
.hamburger-menu {
border: none;
color: #000;
}
.mr-auto {
display: flex;
align-items: center;
background-color: white;
min-width: 100vw;
min-height: 100vh;
}
`;
It's actually rather easy to toggle state but, keep in mind you won't have the graceful height calculation which comes with Bootstrap.
I'll comment out what doesn't seem important to this answer...
import React, { Component } from "react";
//import { Link } from "gatsby";
//import Image from "./image";
import "../../scss/molecules/_topnav.scss";
//const helpers = require("../../helpers");
class Nav extends Component {
state = { collapse: true };
/*
componentDidMount() {
helpers.useIntersect(".navbar-collapse", "navbar-collapsed");
}
*/
constructor(props) {
super(props);
this.brandLogo = this.props.brandLogo;
this.listItems = this.props.pages
//.sort((a, b) => (a.node.navigationOrder || 100) - (b.node.navigationOrder || 100))
.map((page) => page.node.slug && page.node.pageName && !page.node.hideInNavigation && (
<li className="nav-item" key={page.node.id}>
<Link to={`${page.node.slug}`} className="nav-link" title={page.node.pageName}>{page.node.pageName}</Link>
</li>)
);
}
render() {
return (
<>
<nav className={[
"navbar",
"navbar-expand-lg",
"navbar-light",
"fixed-top",
this.state.collapse ? "" : "active"].join(" ")}
>
<a className="navbar-brand" href="/"><Image fluid={this.brandLogo} /></a>
<button
className="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#topnav"
aria-controls="topnav"
aria-expanded={!this.state.collapse}
aria-label="Toggle navigation" onClick={() => {
this.setState({ collapse: !this.state.collapse });
}
}>
<span className="navbar-toggler-icon"></span>
</button>
<div
className={[
"collapse",
"navbar-collapse",
"fade",
!this.state.collapse ? "show" : "",
].join(" ")} id="topnav">
<ul className="navbar-nav ml-lg-auto">{this.listItems}</ul>
</div>
</nav>
</>
);
}
}
export default Nav;
SCSS solution to cover state and mobile -vs- desktop navigation
A simple toggle between display "none" and "block". You can transition transforms to counter the missing height calculation.
We'll use the proper content characters to cover the icons.
It's a bit too much but I'll leave this file complete.
#import "../variables";
#import "../functions";
#import "../vendor/bootstrap/functions";
#import "../vendor/bootstrap/variables";
#import "../vendor/bootstrap/mixins";
#import "../vendor/bootstrap/transitions";
.navbar {
&.navbar-light {
transition: all ease 0.2s;
.navbar-brand {
transition: all ease 0.2s;
.image {
height: auto;
width: rem-value(142);
}
}
.nav-item {
align-items: center;
display: flex;
}
.nav-link {
font-family: $font-family-monospace;
font-size: rem-value(20);
}
#include media-breakpoint-up(md) {
.navbar-collapse {
&:not(.show) {
opacity: 1;
}
}
.nav-item {
margin: auto 1rem;
}
}
#include media-breakpoint-up(lg) {
.nav-item {
&:last-child {
.nav-link {
background-color: $primary;
border-radius: rem-value(3);
color: $white;
margin-left: 1.5rem;
&:hover,
&:active,
&:focus {
background-color: $brand-primary-headings;
}
}
}
}
}
#include media-breakpoint-down(md) {
background-color: $white;
box-shadow: 0 0 1px 1px $gray-300;
padding-top: 0;
padding-bottom: 0;
.navbar-brand {
transform: scale(0.65);
transform-origin: left;
padding-top: 0;
padding-bottom: 0;
}
.navbar-collapse {
&.collapse {
background: white;
margin: 0 -1rem;
height: 0;
transform: scale(0);
transform-origin: top center;
transition: all ease 0.5s;
padding: 1rem;
position: relative;
&.show {
height: calc(100vh - 80px);
transform: scale(1);
}
}
}
.navbar-toggler {
&[aria-expanded="true"] {
.navbar-toggler-icon {
background-image: none;
position: relative;
&:before {
content: "\00d7";
font-family: sans-serif;
font-size: rem-value(40);
line-height: 0.8;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
}
}
}
.nav-item {
border-bottom: 1px solid $gray-300;
margin: 0;
position: relative;
&:before {
content: "\203A";
line-height: 1.2;
font-size: rem-value(30);
color: $brand-primary-headings;
position: absolute;
right: 0.5rem;
width: rem-value(40);
height: rem-value(40);
text-align: center;
}
}
.nav-link {
line-height: 1.8;
width: 100%;
}
}
#at-root .scrolled & {
background-color: $white;
box-shadow: 0 0 1px 1px $gray-300;
padding-top: 0;
padding-bottom: 0;
.navbar-brand {
transform: scale(0.65);
padding-top: 0;
padding-bottom: 0;
}
}
}
}
Example can be seen at devlab.career
Hopefully with this example you can implement this too.

Resources