I am creating a website using bootstrap 5, I would like to have a button that when the user clicks it that a popover appears.
I have added jQuery and the popper.js files to my files. However when I click on the button nothing happens. I have checked the console and it doesn't seem to show any errors. I have no idea what is wrong.
Here is my button code.
<button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="bottom" data-content="Vivamus
sagittis lacus vel augue laoreet rutrum faucibus."><i class="fas fa-shopping-cart" style="color: #fff;">
Cart </i>
</button>
Here is my jQuery code
$(document).ready(() => {
$('[data-toggle="popover"]').popover();
});
Here are the jQuery and popper.js files I have linked.
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
I am wonder if I have linked the wrong version of the files as the bootstrap website wasn't very helpful when it came to this.
Change the data-* attributes with data-bs-* (For example: data-toggle to data-bs-toggle and so on) and change the script to the one provided below to turn on popovers.
In addition, make sure you include Bootstrap assets correctly and everything should be fine. In your case you have not included bootstrap css file so the popover would show up with no styling. Again you can check the below snippet for more details.
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/js/bootstrap.bundle.min.js" integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf" crossorigin="anonymous"></script>
</head>
<body>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-content="Vivamus
sagittis lacus vel augue laoreet rutrum faucibus."><i class="fas fa-shopping-cart" style="color: #fff;">
Cart </i>
</button>
<script>
var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'))
var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
return new bootstrap.Popover(popoverTriggerEl)
})
</script>
</body>
</html>
Not sure if this is too late...but try use the following...
<p>This<i class="fas fa-shopping-cart" style="color: #fff;"></i> triggers a popover on click.</p>
$(document).ready(function() {
$("body").popover({ selector: '[data-toggle="popover"]' });
});
Useful answer here...
https://stackoverflow.com/a/22569369/6790839
Related
The modal shows up just fine when clicking it to open, and the close buttons register that my mouse is hovering over them, but when clicked nothing happens and the modal remains open.
Has anyone encountered/fixed this problem before? All I've seen on here is to add "data-bs-dismiss" but that hasn't made a difference in the modal. I'm new to bootstrap so any and all help would be much appreciated! Code is below, link to full code here -
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name= "viewport" content ="width=device-width, initial-scale=1">
<title>Pokedex</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link href="./CSS/styles.css" rel="stylesheet"/>
<link rel="stylesheet" type="text/css" href="css/styles.css">
<script src="js/scripts.js" defer></script>
</head>
<body>
<div class="pokedex">
<h1 class="pokemon-header">Pokedex</h1>
<ul class="pokemon-list list-group"></ul></div>
<div class="modal" id="modal-container" tabindex="-1" role="dialog" aria-labelledby="modal-container" aria-modal="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title"></h2>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.14.7/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="js/promise-polyfill.js"></script>
<script src="js/fetch-polyfill.js"></script>
</body>
</html>
There are a couple of issues.
Let's start with the way the orange poke-buttons are created.
function addListItem(pokemon) {
let listItem = $('<li class="list-group-item"></li>');
let button = $('<button class="pokemon-button btn btn-warning" data target="#modal-container" data-toggle="modal">' + pokemon.name + '</button>');
listItem.append(button);
pokemonListElement.append(listItem);
button.on('click', function(){
showDetails(pokemon);
});
}
This seems to be fine... But:
let button = $('<button class="pokemon-button btn btn-warning" data target="#modal-container" data-toggle="modal">' + pokemon.name + '</button>');
Take a look at data target="#modal-container . There's a hyphen missing, and instead of this
data target="#modal-container"
it should look like this:
data-target="#modal-container"
Next, there's no need to have this line in your showDetailsModal(pokemon) function:
modalContainer.classList.add('show');
The data-target and data-toggle will cover that part for you.
Finally, your CSS seems to be putting the modal's backdrop on top of the modal. Change this:
#modal-container {
...
z-index: 999;
...
}
to something else (for example, 1051, or you can delete it, and let Bootstrap handle it for you), since the backdrop has a z-index of 1040.
I was able to fix the behavior in the JSFiddle by replacing the following two lines in the showDetailsModal function:
let modalContainer = document.querySelector('#modal-container');
modalContainer.classList.add('is-visible');
with this line:
$('#modal-container').modal('show');
that is one of the methods provided in Bootstrap 4.3 per:
the Bootstrap Modal documentation
Also, it's necessary to add the data-backdrop="false" attribute to your modal-container div in order to maintain the current style/behavior.
This may not be the best solution - I am not sure why your code doesn't work, it seems reasonable to me, but I think it's a good idea to use the default methods provided by the library as other methods (like the close function) may be expecting them and fail to work if you're using an improvised method.
I want to create a search input with button in popover, and when someone click outside of popover get close(not next click, because we need click on input and button in popover).
Because of that I need a function in java script for closing popover to put it on budy (then when user click on budy popover got close)
So here we are, I created this but after several click its not work and even some time it open two time.
And hide button some time working and a lot of time not work.
HTML & source code
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<br>
</i>
<schelps.src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script>
<br><br><br><br>
<button class="btn btn-danger" onclick="hidebtn()">Hide</button>
JavaScript code
const popover = new bootstrap.Popover
(
document.querySelector
(
'[data-toggle="popoversearch"]'
),
{
container: 'body',
html: true,
placement: 'bottom',
sanitize: false,
content: `
<div id="PopoverContent">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search" aria-label="seach popover" aria-describedby="button-addon1">
<button class="btn btn-outline-primary" type="button" data-toggle="popoversearch" data-placement="bottom" data-html="true">
<i class="fas fa-search"></i>
</button>
</div>
</div>`
}
);
function hidebtn() {
popover.hide();
popoversearch.hide();
}
I put the code here
https://jsfiddle.net/Alireza07/fot8mbg6/28/
Thanks for your helps.
In my Sidebar I included a collapse button to show/hide a form. Now I want to maintain the collapse-state when refreshing the page:
If the form was un-collapsed before refreshing the page, it must stay like this after the refresh.
I think I need to use the localStrorage in JavaScript, but I actually don't know how to use this.
This is my HTML:
<!-- Sidebar -->
<ul class="sidebar navbar-nav">
<li class="nav-item active">
<a class="nav-link" data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
<i class="fa fa-filter"></i>
<span>Search Filter</span>
</a>
</li>
</ul>
<!-- Form -->
<div class="collapse" id="collapseExample">
<form>
......
</form>
I found some code only but it seems like it does not work for me..:
var shown = []
// On collapse
shown.remove($(this).attr('id'));
localStorage.setItem('shown', shown);
// On open
shown.push($(this).attr('id'));
localStorage.setItem('shown', shown);
// On page load
var shown = localStorage.getItem('shown');
for (var s in shown) {
$('#collapseExample' + s).show();
}
Thanks for your help!
Here's a Bootstrap 4 collapse example that works. The main difference from the starter template is that I moved the jQuery import to the top of the file so that I could use the document.load function. I've added comments to the code but if anything's still not clear, keep asking questions. Note that I left the vanilla javascript answer for historical comments and in case it helps you, too.
I used the starter page from here:
https://getbootstrap.com/docs/4.0/getting-started/introduction/
And the first collapse example from here:
https://getbootstrap.com/docs/4.0/components/collapse/
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<!-- Bootstrap CSS -->
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous"
/>
<title>Hello, world!</title>
<!-- jQuery -->
<script
src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"
></script>
<script>
$(function() {
// store a reference to the collapse div so that
// we don't have to keep looking it up in the dom
const collapseExample = $("#collapseExample");
// register a callback function to the collapse div that
// will be called every time the collapse is opened.
collapseExample.on("shown.bs.collapse", function() {
// since we know that that this function is called on
// open, we'll set the localStorage value to "show"
localStorage.setItem("collapseExample", "show");
});
// register a callback function to the collapse div that
// will be called every time the collapse is closed.
collapseExample.on("hidden.bs.collapse", function() {
// since we know that that this function is called on
// open, we'll set the localStorage value to "hide"
localStorage.setItem("collapseExample", "hide");
});
// Since this function runs on page load (meaning only once), we can
// check the value of localStorage from here and then call the
// bootstrap collapse methods ourselves:
// Check the value of the localStorage item
const showExampleCollapse = localStorage.getItem("collapseExample");
// Manipulate the collapse based on the value of the localStorage item.
// Note that the value is determined by lines 36 or 44. If you change those,
// then make sure to check that the comparison on the next line is still valid.
if (showExampleCollapse === "show") {
collapseExample.collapse("show");
} else {
collapseExample.collapse("hide");
}
});
</script>
</head>
<body>
<main>
<p>
<a
class="btn btn-primary"
data-toggle="collapse"
href="#collapseExample"
role="button"
aria-expanded="false"
aria-controls="collapseExample"
>
Link with href
</a>
<button
class="btn btn-primary"
type="button"
data-toggle="collapse"
data-target="#collapseExample"
aria-expanded="false"
aria-controls="collapseExample"
>
Button with data-target
</button>
</p>
<div class="collapse" id="collapseExample">
<div class="card card-body">
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus
terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer
labore wes anderson cred nesciunt sapiente ea proident.
</div>
</div>
</main>
<!-- Optional JavaScript -->
<!-- Popper.js, then Bootstrap JS -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"
></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"
></script>
</body>
</html>
END BOOTSTRAP ANSWER
BEGIN VANILLA JAVASCRIPT ANSWER
Here's a basic, self-contained version of what you seem to be trying to do. It's not pretty, but hopefully, it's clear.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
function getCollapsed() {
const state = localStorage.getItem('collapsed');
if(state === 'collapsed'){
return true;
}
return false;
}
function getStatus(){
const resultDiv = document.getElementById('result');
const isCollapsed = getCollapsed();
if(isCollapsed){
resultDiv.innerHTML = "collapsed";
}else{
resultDiv.innerHTML = "un-collapsed";
}
}
function toggleCollapse(){
const isCollapsed = getCollapsed();
if(isCollapsed){
localStorage.setItem('collapsed', 'un-collapsed');
}else{
localStorage.setItem('collapsed', 'collapsed');
}
getStatus();
}
</script>
</head>
<body onload="getStatus()">
<div>
<button onclick="toggleCollapse()">Toggle Collapse</button>
</div>
<div id="result"></div>
</body>
</html>
I'm using the trigger as hover, but when I click on a link with this function the tooltip does not disappear, it will be disturbing on the screen forever
the tooltip is instantiated with this code
$('[data-toggle="tooltip"]').tooltip({
container: 'body',
trigger: 'hover'
});
in tags everything works perfectly, and in some cases works too, I do not know why some happen this, could someone give me a light?
Edit: I've also tried using this code to hide the tooltip with the click event
$(document).ready(function(){
$('[data-toggle="tooltip"]').click(function () {
$('[data-toggle="tooltip"]').tooltip("hide");
});
});
But it doesn't work
Edit*: Picture of how it is (the text is in Portuguese)
Edit**: HTML code
<ul style="clear: both;" class="pager wizard">
<li class="button-previous previous"><a title="Voltar" data-toggle="tooltip"><i class="fa fa-arrow-left"></i></a></li>
<li class="voltar"><a title="Voltar" data-toggle="tooltip"><i class="fa fa-arrow-left"></i></a></li>
<li class="finalizar"><a>Finalizar<i class="fa fa-check" style="padding-left:5px;"></i></a></li>
<li class="next"><a class="competencia-stripe" data-toggle="tooltip" title="Continuar"><i class="fa fa-arrow-right" ></i></a></li>
</ul>
This Code Use To tag Click to Hide Hover and You Remove Click Event From below code to hover not hide.
Try This Code...! It's Worked.
$('[data-toggle="tooltip"]').tooltip({
trigger : 'hover'
})
$('.btn-secondary').click(function(){
$('[data-toggle="tooltip"]').tooltip('hide');
});
.tooltiphide {
margin-top: 50px;
margin-top: 50px;
}
<!DOCTYPE html>
<html>
<head>
<title>Boostrap Tooltip</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</head>
<body>
<div class="tooltiphide">
<a href="#" class="btn btn-secondary" data-toggle="tooltip" data-placement="top" title="Tooltip on top">
Tooltip on top
</a>
<a href="#" class="btn btn-secondary" data-toggle="tooltip" data-placement="right" title="Tooltip on right">
Tooltip on right
</a>
<a href="#" class="btn btn-secondary" data-toggle="tooltip" data-placement="bottom" title="Tooltip on bottom">
Tooltip on bottom
</a>
<a href="#" class="btn btn-secondary" data-toggle="tooltip" data-placement="left" title="Tooltip on left">
Tooltip on left
</a>
</div>
</body>
</html>
This is because trigger is not set. The default value for trigger is 'hover focus', thus the tooltip stay visible after a button is clicked, until another button is clicked, because the button is focused.
So all you have to do is to define trigger as 'hover' only. Below the same example you have linked to without persisting tooltips after a button is clicked :
$('[data-toggle="tooltip"]').tooltip({
trigger : 'hover'
})
the doc example in a fiddle -> http://jsfiddle.net/vdzvvg6o/
I tried to hide all tooltips as soon as the page loads and it worked
$([data-toggle="tooltip"]).on('load', function(){
$('[data-toggle="tooltip"]').tooltip("hide");
});
but I believe it is not the best solution and I seek a better, another solution that came to me was this
window.addEventListener("click", function (event) {
$('.tooltip.fade.top.in').tooltip("hide");
}
The <a> tag defines a hyperlink, which is used to link from one page to another.
so it is not appropriate for one-page actions like this. but you can fix this issue by loses focus on the element by .focusout()
$(document).ready(function(){
$('[data-toggle="tooltip"]').click(function(){
$(this).focusout();
});
});
Questions I've already looked at:
Bootstrap JavaScript not working
twitter bootstrap drop down suddenly not working
Complete list of reasons why a css file might not be working
My Bootstrap styles seem to have suddenly stopped being applied, resulting in pages that look something like this. I'm using the layout generated by ASP.NET MVC 5, so there should be a navbar at the top, among other things. Ignore the red banner, the button doesn't show on that page anyway.
Nothing looks amiss in the dev tools -- console, network, etc. all look normal with no errors. All the files are loaded, and changing their order changes nothing. All of the .css and .js files are loaded from the local file system. I even reverted to a commit from yesterday, when the site was working fine, but the site still displays incorrectly.
I've tried turning it off and on again, now I'm out of ideas.
Edit: Same results, no matter the browser. I'm at a total loss here.
Code, as requested:
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Log in</title>
<link href="/Content/bootstrap.css" rel="stylesheet"/>
<link href="/Content/Site.css" rel="stylesheet"/>
<link href="/Content/css/select2.css" rel="stylesheet"/>
<link href="/Content/alertify.css" rel="stylesheet"/>
<script src="/Scripts/modernizr-2.6.2.js"></script>
<script src="/Scripts/modernizr-2.8.3.js"></script>
<script src="/Scripts/jquery-3.1.1.js"></script>
<script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/respond.js"></script>
<script src="/Scripts/alertify.js"></script>
<script src="/Scripts/Custom/JavaScript/utility.js"></script>
<script src="/Scripts/jquery.mask.js"></script>
<script src="/Scripts/autosize.js"></script>
<script src="/Scripts/Custom/register-modal.js"></script>
<script>
//<!-- Google Analytics -->
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date(); a = s.createElement(o),
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
ga('create', 'shh', 'none');
ga('send', 'pageview');
//<!-- End Google Analytics -->
</script>
<!-- FontAwesome -->
<link href="/Content/FontAwesome/fontawesome-all.css" rel="stylesheet" />
</head>
</html>
change the <nav> tag in layout file with this
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarColor01" aria-controls="navbarColor01" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarColor01">
<ul class="navbar-nav mr-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="#">About</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search">
<button class="btn btn-secondary my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
tl;dr OP updated from Bootstrap 3 -> 4 without updating HTML.
A week ago, I updated to Bootstrap v4(a?) via NuGet, without paying attention to the change in major version number. Apparently my cache didn't get cleared until a week later (when I asked this question), so I had forgotten the update even happened.
Bootstrap 4 is a major rework, so the bulk of my Bootstrap HTML became invalid.
Reverting Bootstrap fixes everything.