Vertical alignment in sidebar - html

How would I align items in a sidebar like this:
See image
my main problems are the formatting for the footer being fixed to the bottom and the main sidebar container overflowing and scrolling but still being between the sidebar header and the sidebar bottom element text container, so not overlapping either while having that element be scrollable without the whole sidebar scrolling
what i have so far:
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
<div class="container-fluid">
<div class="row">
<div class="col-4 bg-dark text-white" style="height: 100vh; width:250px;">
<!-- <div class="col bg-primary">
test
</div>
<div class="col bg-danger">
test 2
</div>
<div class="col bg-primary" style="position: fixed; bottom: 0;">
test 3
</div> -->
<div class="d-flex flex-column justify-content-start mb-3">
<div class="p-2 bg-primary">
Flex item 1
</div>
<div class="p-2 bg-danger flex-grow-1">
Flex item 2
</div>
<div class="p-2 bg-primary" style="position:fixed; bottom:0;">
Flex item 3
</div>
</div>
</div>
<div class="col bg-secondary text-white">
main body
</div>
</div>
<!-- <div class="row">
<div class="col bg-secondary text-white">
main body
</div>
</div> -->
</div>
using bootstrap 5.3.0 alpha1

Here's a minimal example of how to create a full page layout with a container that should scroll on overflow using Bootstrap V5.3.
Read the docs if you like to learn how it works.
Read about flex-grow-1 or if you're new to flex start here.
Learn how overflow works.
nav {
height: 100vh;
max-height: 100vh;
background: lightgreen;
}
main {
background: lightyellow;
}
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
</head>
<body>
<div class="container-fluid px-0">
<div class="row gx-0">
<nav class="col-4 p-2 d-flex flex-column gap-1">
<div class="">
<h5>
Sidebar header
</h5>
</div>
<div class="">
Some content
</div>
<div class="">
Some other content
</div>
<div class="flex-grow-1 overflow-auto">
sidebar scroll
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> end sidebar scroll
</div>
<div class="">
Sidebar footer
</div>
</nav>
<main class="col">
main body
</main>
</div>
</div>
</body>
</html>
If <main> should also overflow:scroll at 100vh.
Add in CSS:
main {
height: 100vh;
max-height: 100vh;
}
and in HTML:
<main class="col overflow-auto">
If <main> can grow beyond the viewport height and you want <nav> to grow along with it.
You could wrap the content inside col-4 in an absolute positioned container that fills col-4 and therefore let it grow beyond 100vh height while keeping the overflow scroll if <main> is smaller, for example:
nav {
min-height: 100vh;
background: lightgreen;
}
nav #overflow-container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
main {
background: lightyellow;
}
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
</head>
<body>
<div class="container-fluid px-0">
<div class="row gx-0">
<nav class="col-4 position-relative">
<div class="p-2 d-flex flex-column gap-1" id="overflow-container">
<div class="">
<h5>
Sidebar header
</h5>
</div>
<div class="">
Some content
</div>
<div class="">
Some other content
</div>
<div class="flex-grow-1 overflow-auto">
sidebar scroll
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> end sidebar scroll
</div>
<div class="">
Sidebar footer
</div>
</div>
</nav>
<main class="col">
main body
</main>
</div>
</div>
</body>
</html>
If <nav> and <main> should stack vertically at a smaller screen size.
In the HTML make .row a flex-column by default and a flex row on the medium breakpoint with flex-md-row. Then change col-4 to col-md-4.
In the CSS add a media query, using Bootstrap's medium breakpoint width.
Note: Snippet below is based on the example above with an absolute positioned container, but the same logic can also be applied to the other examples.
nav {
min-height: 100vh;
background: lightgreen;
}
main {
background: lightyellow;
}
#media (min-width: 768px) {
nav #overflow-container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
}
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
</head>
<body>
<div class="container-fluid px-0">
<div class="row gx-0 flex-column flex-md-row">
<nav class="col-md-4 position-relative">
<div class="p-2 d-flex flex-column gap-1" id="overflow-container">
<div class="">
<h5>
Sidebar header
</h5>
</div>
<div class="">
Some content
</div>
<div class="">
Some other content
</div>
<div class="flex-grow-1 overflow-auto">
sidebar scroll
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> end sidebar scroll
</div>
<div class="">
Sidebar footer
</div>
</div>
</nav>
<main class="col">
main body
</main>
</div>
</div>
</body>
</html>

Related

Stop sidebar from overlapping sticky footer

I'm working on a site for a class project and everything is working fine except when I tried to make the footer sticky the sidebar overlaps the footer when content is added dynamically.
I have the sidebar height set to 90vh because I could not figure out how to get the background color to take up the full height of the sidebar when there was no content I set the sidebar overflow to auto which was working fine but when I try to make the footer sticky it works find until the content grows to big. Scrollbars do appear but the sidebar overlaps the footer.
Here is the html & css:
body {
display: flex;
min-height: 100vh;
flex-direction: column;
}
main {
flex: 1 0 auto;
}
.main-image {
background-image: url(../images/crypto.jpg);
background-repeat: no-repeat;
height: 90vh;
max-width: 100%;
clip: rect(0, 400px, 200px, 0);
}
.sidebar {
height: 90vh;
overflow: auto;
}
footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
}
<!DOCTYPE html>
<html>
<head>
<title>Crypto & Cocktails </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link rel="stylesheet" href="./assets/css/style.css">
<link rel="icon" href="./assets/images/favicon.ico">
</head>
<body>
<!-- header -->
<header id="top">
<div class="row">
<div class="col s12 center #26a69a teal lighten-1">
<img src="assets/images/cryptococktailsheader.jpg" class="responsive-img" alt="Crypto & Cocktails" />
</div>
</div>
</header>
<main>
<div class="row">
<!-- sidebar -->
<div class="col s12 l2 #00695c teal darken-3 sidebar">
<span class="flow-text center">
<h5 class="white-text">Search Coinbase</h5>
<form id="coin-search" action="">
<input id="coin-input" type="text" class="white" name="coin-input"
placeholder="Cryptocurrency Ticker">
<button class="btn btn-lg btn-primary submitButton">Search</button>
</form>
</span>
<div id="myCoins" class="col-12"></div>
</div>
<div class="col s12 l10 content">
<div class="row">
<div class="col s12 l3 ">
<h2 id="coin-name"></h2>
<span id="coin-display" class="flow-text"></span>
<h3 id="drinkName"></h3>
<span id="drinkImg"></span>
<a class="right hide-on-med-and-up" href="#top">Back to top</a>
</div>
<div class="col s12 l7 main-image hide-on-small-only"></div>
</div>
</div>
</div>
</main>
<footer class="#26a69a teal lighten-1 center">
<div class="container">
<div class="row">
<div class="col l12">
<h5 class="white-text">Developers - Contact Us</h5>
</div>
</div>
</div>
<div class="footer-copyright">
<div class="container">
© 2021 Copyright
</div>
</div>
</div>
</footer>
</div>
<!-- jQuery CDN -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<!-- Materialize Framewrk -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.0/jquery-ui.js"></script>
<!-- Custom Scripts -->
<script src="./assets/scripts/main.js"></script>
<script src="./assets/scripts/cocktail.js"></script>
<script src="./assets/scripts/coinbase.js"></script>
</body>
We just had to add the z-index: 1; to the footer.

How can I get a simple 3 stacked column layout in bootstrap 5 to be 100vh

I picked up Bootstrap 5 today
I'm not able to make a 3 stacked column layout with box-1, box-2 and box-3 on-top of each other take 100vh
I've pasted a redacted version of the code below, it really is three boxes stacked on top of each other. I can do this in CSS Grid and Flexbox but not with Bootstrap.
Here are the methods I've already tried which have not worked:
set body and html to height: 100vh
set container to height 100vh - this makes each box 100vh ora box-1 takes 100vh, box-2 overflows up to another 100vh, likewise box-3
make a wrapper class around the content of the body and set that to height 100vh
repeated 1)-3) with utility class vh-100
Any suggestions please?
Thanks
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<body>
<section class="container box-1">
<div class="row">
<div class="col">
</div>
</div>
</section>
<section class="container box-2">
<div class="row">
<div class="col">
</div>
</section>
<section class="container box-3">
<div class="row">
<div class="col">
</div>
</div>
</section>
</body>
Seems to me you can dramatically simplify this. I'm not sure why you'd need rows or columns if there's only ever one of each per container. You don't even seem to need more than one container. Let's just us a basic flex column, per the docs.
/* all styles for demo only */
.d-flex {
background: #eee;
}
.box-1:nth-child(even) {
background: pink;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<body>
<div class="container d-flex flex-column vh-100 p-0">
<section class="box-1 flex-fill">Section</section>
<section class="box-1 flex-fill">Section</section>
<section class="box-1 flex-fill">Section</section>
</div>
</body>
If you do happen to need the containers and inner structure, just move the flex-fill class out to the rows (and just use one container). It'll work the same.
/* all styles for demo only */
.row {
background: #eee;
}
.row:nth-child(even) {
background: pink;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<body>
<div class="container d-flex flex-column vh-100">
<div class="row flex-fill">
<div class="col">
<section class="box-1">Section</section>
</div>
</div>
<div class="row flex-fill">
<div class="col">
<section class="box-1">Section</section>
</div>
</div>
<div class="row flex-fill">
<div class="col">
<section class="box-1">Section</section>
</div>
</div>
</div>
</body>

Bootstrap 4 - how to make scrollspy work without using nav or list-group?

Is there a way to make scrollspy work without using nav or list-group?
Bootstrap documentation for scrollspy states that it may be used only on nav or list group components. DOCUMENTATION
How it works
Scrollspy has a few requirements to function properly:
If you’re building our JavaScript from source, it requires util.js.
It must be used on a Bootstrap nav component or list group.
Scrollspy requires position: relative; on the element you’re spying on, usually the <body>.
When spying on elements other than the <body>, be sure to have a height set and overflow-y: scroll; applied.
Anchors (<a>) are required and must point to an element with that id.
This question is similar, but for Bootstrap 3 (not 4) and the answer is to add role="tablist". Well, it doesn't work here. There are many questions on SO about scrollspy, but mostly for Bootstrap 3.
CODE:
/*DEMO*/
nav{top:50%;left:1.5rem;transform:translateY(-50%)}
nav a{display:block;width:20px;height:20px;margin-bottom:.5rem}
/*COLORS*/
nav a{background:black}
nav a.active{background:red}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body data-spy="scroll" data-target="#nav" data-offset="0">
<section class="container-fluid">
<div class="row">
<div id="item-1" class="col-12 vh-100 bg-primary"></div>
<div id="item-2" class="col-12 vh-100 bg-warning"></div>
<div id="item-3" class="col-12 vh-100 bg-danger"></div>
<div id="item-4" class="col-12 vh-100 bg-success"></div>
<div id="item-5" class="col-12 vh-100 bg-info"></div>
</div>
</section>
<nav id="nav" class="d-flex flex-column position-fixed">
</nav>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
</body>
</html>
You can overcome this by using the required class list-group-item and reset the CSS like you want:
/*DEMO*/
nav {
top: 50%;
left: 1.5rem;
transform: translateY(-50%)
}
#nav a {
display: block;
width: 20px;
height: 20px;
margin-bottom: .5rem;
padding: 0;
border: none;
border-radius: 0;
}
/*COLORS*/
#nav a {
background: black
}
#nav a.active {
background: red
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body data-spy="scroll" data-target="#nav" data-offset="0">
<section class="container-fluid">
<div class="row">
<div id="item-1" class="col-12 vh-100 bg-primary"></div>
<div id="item-2" class="col-12 vh-100 bg-warning"></div>
<div id="item-3" class="col-12 vh-100 bg-danger"></div>
<div id="item-4" class="col-12 vh-100 bg-success"></div>
<div id="item-5" class="col-12 vh-100 bg-info"></div>
</div>
</section>
<nav id="nav" class="d-flex flex-column position-fixed">
</nav>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Justify content block bootstrap 4

I have this code:
.banner {
background: #f9f9f9;
width: 300px;
height: 60px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<section class="banners mb-4">
<div class="container">
<div class="d-flex justify-content-between">
<div class="banner"></div>
<div class="banner"></div>
<div class="banner"></div>
</div>
</div>
</section>
I need on mobile and tablets display: block these elements banner with spacing. How I can do it with flex? Now I get elements on inline.
Based on viewport you could use this d-* classes
So this
<div class="d-flex justify-content-between">
would be
<div class="d-lg-flex justify-content-between">
This will make .banner block(the default behavior of div) till large viewport
You can change the direction on small screen (https://getbootstrap.com/docs/4.2/utilities/flex/#direction)
.banner {
background: red;
border:1px solid;
min-height: 60px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<section class="banners mb-4">
<div class="container">
<div class="d-flex flex-column flex-sm-row justify-content-between">
<div class="banner col m-2"></div>
<div class="banner col m-2"></div>
<div class="banner col m-2"></div>
</div>
</div>
</section>

How to Set Column Heights - Bootstrap 4?

I am playing around with bootstrap 4 and I am not sure how to get my heights correctly. I have a "side nav", "header", "main" and "footer".
I want "main" to take up most of the height. However for some reason my heights must be messed up as the side nave does not go all the way down and I got this white chunk in the bottom left hand corner.
If you do full screen on my code you will see it.
body,
html,
.container-fluid {
height: 100%;
}
.wrapper {
display: flex;
align-items: stretch;
}
#sidebar {
background-color: blue;
color: white;
}
#media (max-width: 768px) {
#sidebar {
min-width: 80px;
max-width: 80px;
text-align: center;
margin-left: -80px !important;
}
}
<!DOCTYPE html>
<html>
<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>test</title>
<!-- Bootstrap CSS CDN -->
<!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
<!-- Our Custom CSS -->
<link rel="stylesheet" href="style4.css">
</head>
<body>
<div class="wrapper h-100">
<!-- Sidebar Holder -->
<nav id="sidebar">
<div class="sidebar-header">
<h3>Bootstrap Sidebar</h3>
</div>
<ul class="list-unstyled components">
<li>
<a>
Home
</a>
</li>
</ul>
</nav>
<div class="container-fluid ">
<div class="row h-100">
<div class="col-12" style="background-color: red;">
One of three columns
</div>
<main class="col-12 h-100" style="background-color: yellow;">
test
</main>
<div class="col-12" style="background-color: pink;">
test2
</div>
</div>
</div>
</div>
</body>
</html>
The problem currently is the that using h-100 on the row, makes the child col-12 also set to h-100 exceed the viewport height which causes scrolling and the whitespace under the sidebar.
As of Bootstrap 4.1, there is a flex-fill util class that is helpful for this layout...
.flex-fill {
flex: 1 1 auto;
}
In this case, you can use it so that the child divs grow to fill remaining height. Just set min-height on the .wrapper:
.wrapper {
min-height: 100vh;
}
And then, make container-fluid also a flexbox container (using d-flex). Use the util flex-fill to make row and the middle col-12 fill height:
<div class="wrapper d-flex">
<!-- Sidebar Holder -->
<nav id="sidebar">
<div class="sidebar-header">
<h3>Bootstrap Sidebar</h3>
</div>
<ul class="list-unstyled components">
<li>
<a>
Home
</a>
</li>
</ul>
</nav>
<div class="container-fluid d-flex flex-column">
<div class="row flex-fill flex-column">
<div class="col-12" style="background-color: red;">
One of three columns
</div>
<main class="col-12 flex-fill" style="background-color: yellow;">
test
</main>
<div class="col-12" style="background-color: pink;">
test2
</div>
</div>
</div>
</div>
https://www.codeply.com/go/VvogWj44cS