This is a similar question to How can I make navbar items with vue-router-links to toggle the navbar? but I am not allowed to comment there, and the solution given doesn't work me anyway.
I am using Vue 3 and Bootstrap 5 and the following code works exactly as the standard Bootstrap code does i.e. toggling the hamburger menu opens and closes the menu but clicking a link does nothing (other than correctly route to the page being clicked, meaning user has to then tap hamburger menu again to close)
NavBar component:
<template>
<nav class="navbar navbar-dark bg-dark navbar-expand-sm">
<div class="container-fluid">
<router-link class="navbar-brand" to="/">Birch Farm</router-link> |
<button class="navbar-toggler" type="button"
:class="visible ? null : 'collapsed'"
data-bs-toggle="collapse"
data-bs-target="#navContent"
aria-controls="navContent"
:aria-expanded="visible ? 'true' : 'false'"
#click="visible = !visible"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item active">
<router-link class="nav-link px-3" active-link="active" to="/" #click="visible = !visible">Home</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link px-3" to="/camping" #click="visible = !visible">Camping & Caravanning</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link px-3" to="/fishing" #click="visible = !visible">Cat Rough Fishery</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link px-3" to="/contact" #click="visible = !visible">Contact Us</router-link>
</li>
</ul>
</div>
</div>
</nav>
</template>
<script setup>
import {ref} from 'vue'
const visible = ref(false);
</script>
<script>
export default {
name: "NavBar",
created() {},
data() {},
props: {},
methods: {},
components: {}
};
</script>
<style lang="scss" scoped></style>
Not having any of the 'visible' stuff works exactly the same way - this was added when trying the solution given in the above link.
"toggling the hamburger menu opens and closes the menu but clicking a link does nothing (other than correctly route to the page being clicked"
That's how the Bootstrap Navbar works. It doesn't collapse/hide automatically after clicking a link. Normally you'd have to do something like this to close the Navbar after clicking a link.
But when using Vue you would toggle the collapse class as needed on the navbar-collapse div using your visible value...
<div class="navbar-collapse" :class="!visible?'collapse':''" id="navContent">
Demo: https://codeply.com/p/lHTzN4amfe
You have to follow this guide if you are using bootstrap via NPM. As long as I see, the way to use it is different in Angular or React, for example.
In addition to that, if you want to use bootstrap in your project and set it up the easiest way possible, is to use the CDN, I will show you how:
In your main layout, inside the head tag, put this:
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
And inside your body tag, this:
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"></script>
I had the same issue, bootstrap (5.1.3) and Vue (3.2.36). So I installed bootstrap-vue-3 (0.1.13) and use and to make it work.
Also without "navbar-light bg-light) the hamburger icon didn't appear at first.
Hope this helps.
<template>
<nav class="navbar navbar-expand-lg fixed-top navbar-light bg-light">
<div class="container-fluid">
<RouterLink class="navbar-brand" to="/">
<img class="logo" src="../assets/svg/logo.svg" />
</RouterLink>
<b-button
v-b-toggle.collapse-1
variant="primary"
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#menuItems"
aria-controls="menuItems"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</b-button>
<b-collapse id="collapse-1" class="mt-2 collapse navbar-collapse">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<RouterLink class="nav-link" to=" /">home </RouterLink>
</li>
<li class="nav-item">
<RouterLink class="nav-link" to=" /something"
>something
</RouterLink>
</li>
<li class="nav-item">
<RouterLink class="nav-link" to="/about"
>about
</RouterLink>
</li>
</ul>
<form class="d-flex">
<input
class="form-control me-2"
type="search"
placeholder="Search"
aria-label="Search"
/>
<button class="btn btn-outline-success" type="submit">
Search
</button>
</form>
</b-collapse>
</div>
</nav>
I changed data-toggle to data-bs-toggle and data-target to data-bs-target and it worked.
My main.js(main entry file) has this
...
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap";
...
I found a tweak in this other thread for Vue 3 / Bootstrap 5 / vue-router :
How to hide collapsible Bootstrap navbar on click
Adding a simple span tag around menu label and inside li / routerling worked for me:
<div class="collapse navbar-collapse" id="navigation">
<ul class="navbar-nav me-auto mb-2 mb-sm-0">
<li class="nav-item">
<RouterLink class="nav-link" to="/"><span data-bs-target="#navigation" data-bs-toggle="collapse">Menu 1</span></RouterLink>
</li>
<li class="nav-item">
<RouterLink class="nav-link" to="/ventes.html"><span data-bs-target="#navigation" data-bs-toggle="collapse">Menu 2</span></RouterLink>
</li>
</ul>
I hope it helps!
I thought to share my workaround/solution for this specific issue.
Do not use the router-link component, rather trigger the navigation manually via the push method in vue-router by handling the click event in vue.
This allows for a "static" layout of the HTML so that you can preserve the functionality in Bootstap which allows for controlling the collapsing of the navbar via data attributes.
In order to trigger the active navigation style you can use class binding in vue and the route.name value from vue-router. It would also work with the path given slight modification.
Here is a basic example:
<script setup>
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
const navigate = name => router.push({ name })
</script>
<template>
<div class="container">
<span class="navbar-brand">EXAMPLE NAVBAR</span>
<button class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNavAltMarkup"
aria-controls="navbarNavAltMarkup"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<li class="nav-item">
<span :class="['nav-link', route.name === 'camping' ? ' active' : '']"
role="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNavAltMarkup"
#click="navigate('camping')">CAMPING</span>
</li>
<li class="nav-item">
<span :class="['nav-link', route.name === 'fishing' ? ' active' : '']"
role="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNavAltMarkup"
#click="navigate('fishing')">FISHING</span>
</li>
</div>
</div>
</div>
</template>
<li class="nav-item mx-1">
<NuxtLink class="btn nav-button nav-text" to="/eventi">
<span data-bs-target="#navbarSupportedContent" data-bs-toggle="collapse">Servizi</span>
</NuxtLink>
</li>
I solved adding a span tag with data-bs-target="#navbarSupportedContent" and data-bs-toggle="collapse" around the name of the links (in my case they are NuxtLink but I think works either with Router-link)
I have written a simple html and css file but my css is not working for the second last link i.e. for the link to logout
here is the code to my HTML file
<nav class="navbar navbar-expand-md navbar-dark">
<a class="navbar-brand" href="#">
<img src="../../../assets/logo.JPG" class="d-inline-block img-fluid align-top" alt="">
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse"
data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id = "navbarSupportedContent" >
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<div *ngIf="email" class="navbar-text custom float-left">
{{email}}
</div>
</li>
<li class="nav-item">
<a [routerLink]=" ['/'] " class="nav-link">
<fa-icon [icon] = "faHome" primarycolor = "black"></fa-icon>
Home</a>
</li>
<li class="nav-item">
<a *ngIf="!email" [routerLink]=" ['/signin'] "
routerLinkActive="active" class="nav-link">
<fa-icon [icon] = "faSignInAlt" primarycolor = "black"></fa-icon>
signIn</a>
</li>
<li class="nav-item">
<a *ngIf="!email" routerLinkActive="active"
[routerLink]=" ['/signup'] " class="nav-link">
<fa-icon [icon] = "faUserPlus" primarycolor = "black"></fa-icon>
signUp</a>
</li>
<li class="nav-item">
<a *ngIf="email" (click)="handleSignOut()" class="nav-link">
<fa-icon [icon] = "faSignOutAlt" primarycolor = "black"></fa-icon>
Log Out</a>
</li>
<li class="nav-item">
<a *ngIf="email" routerLinkActive="active" [routerLink]=" ['/addpost']"
class="nav-link btn btn-warning text-primary">
Post Your Story</a>
</li>
</ul>
</div>
</nav>
Here is the code to my css file
.active{
background-color: purple;
}
.custom{
color: black;
}
nav{
background-color: #ffffff;
}
li>a:link{
color: black;
border-radius: 15px;
}
li>a:visited{
color: black;
border-radius: 15px;
}
I don't know what is happening here
inline CSS in that link is working quite good
I basically want my logout to be black
It is very difficult to guess based on the small excerpt. The best way is to use the computed tab of the chrome debugging tool. You need to inspect the element, go to the computed tab and expand the CSS property. You would see who sets and overrides the property value.
There is a good article on how to debug css.
Have you tried targeting it directly by giving it a unique class or id and using that in the css?
Have you tried putting "!important" after the color you want in the css?
It looks like you are using an external css library. Some of the css from external libraries can be hard to override. "!important" helps with that sometimes.
I am trying to make a navbar that changes the style of a particular navbar link to active as the user scrolls down the page. I am trying to do this using Bootstrap's scrollspy feature.
I checked and there are many comprehensible tutorials on this (e.g. https://www.w3schools.com/bootstrap/bootstrap_scrollspy.asp or https://mdbootstrap.com/docs/standard/navigation/scrollspy/#example-3).
Although I believe I followed them to the letter, the effect just does not seem to work. I am afraid this may have to do something with the changes to mechanics of the spyscroll feature due to the abandonment of JQuery by BS5. But it very well may by an error in my code, although I did my best to follow the tutorials to the letter.
My code:
(a) included external files:
<link rel="stylesheet" href="BS5/css/bootstrap.min.css" />
<link href="https://fonts.googleapis.com/css2?family=Ubuntu&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="BS5/css/styles.css" /> <!-- BS customising css -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="BS5/js/bootstrap.js"></script>
<script src="BS5/js/jsko.js"></script> <!-- non related custom scripts -->
(b) style tag
<style>
body
{
position: relative;
}
</style>
(c) body tag
<body data-spy="scroll" data-target="#navbarko">
(d) navbar tag
<nav class="navbar navbar-expand-lg navbar-light bg-light fixed-top nav-larger" id="navbarko">
<div class="container">
<a class="navbar-brand" href="#"><img src="logo.png"/></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#home">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#mission">Our mission</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#debt">Debt</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#finadv">Finland</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#references">References</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#contact">Contact</a>
</li>
</ul>
</div>
</div>
</nav>
(e) beginning of the section tags throughout the page:
<section class="feature grad_third" id="mission">
<section class="feature grad_third" id="debt">
<section class="feature grad_third" id="finadv">
<section class="companies references" id="references">
<section class="feature grad_third" id="contact">
Many thanks beforehand for your time and help.
Things have changed slightly in Bootstrap 5 - and the W3Schools tutorial is Bootstrap 4.
So you need to change your body tag to (note the 'bs', for Bootstrap):-
data-bs-spy="scroll"
More on this here:-
https://getbootstrap.com/docs/5.0/migration/#javascript
Data attributes for all JavaScript plugins are now namespaced to help
distinguish Bootstrap functionality from third parties and your own
code. For example, we use data-bs-toggle instead of data-toggle.
I have a header that I plan to use on the top of all my pages. I'd like to keep it in a separate file (something I'm used to doing with php, but I'm new to the world of Bootstrap); however, I am not sure how I would handle dynamically assigning the active class to the nav-item that represents the current page. Does Bootstrap (4) have a baked-in solution for this sort of thing? I've been searching around but haven't found a good solution yet. Thanks in advance!
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-light bg-transparent fixed-top">
<div class="container">
<a class="navbar-brand" href="#">My Site</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home
<span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Work</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Blog</a>
</li>
</ul>
</div>
</div>
</nav>
Bootstrap includes some jQuery and is not just CSS. However, you can always run some JavaScript or jQuery on page load that toggles the class based on reading an element when the page is loaded. For example you could:
1) have an identifier on each page (eg. class name inside an element on a page that holds the page's name/value). Example:
<h1 class="page-lookup">
Home
</h1>
2) set you jQuery in a function to read for class and grab the value of the element with a .val(). Example:
const activePage = $(".page-lookup").val()
3) Add an id on each in your navbar to uniquely identify them. Example:
<li id="home-page" class="nav-item">
<a class="nav-link" href="#">Home</a>
</li>
4) Run a switch case that looks up the stored value (activePage) for a match. In the case that matches you can run jQuery to update the class to include the "active" syntax that will trigger Bootstrap's formatting.
Example:
switch (activePage) {
case Home:
$('#home-page).attr("class", "nav-item active");
break;
case About:
$('#about-page).attr("class", "nav-item active");
break;
}
I'm using Angular 2 with Bootstrap 4. I can get the active tab to change using the following code:
navbar.component.html
<nav class="navbar navbar-fixed-top navbar-light bg-faded">
<button class="navbar-toggler hidden-sm-up" type="button" data-toggle="collapse" data-target="#navbar">
☰
</button>
<div class="collapse navbar-toggleable-xs" id="navbar">
<div class="container">
<a class="navbar-brand" [routerLink]="['']">My App</a>
<ul class="nav navbar-nav navbar-right">
<li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact:
true}">
<a class="nav-link" [routerLink]="['']">Home<span class="sr-only">(current)</span></a>
</li>
<li class="nav-item" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}">
<a class="nav-link" [routerLink]="['/about']">About</a>
</li>
<li class="nav-item" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}">
<a class="nav-link" [routerLink]="['/example']">Example</a>
</li>
</ul>
</div>
</div>
</nav>
The line:
[routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"
works well at changing to the currently active tab, but when I navigate to a component using something like:
this.router.navigate(['']);
The active tab doesn't change. Is there a way to change the active tab when navigating like above?
So basically you want to make your high-lighting in a service and call that service to apply your style when your URL equals a specific state. this is done by using
this.router.url === '/myroute'
here is my plunker. NOTE that the active tab will change whether you use the links or the buttons. The buttons are what use the this.router.navigate(['']); like you asked in the question