Reputation: 34
The challenge: create a nav bar that has a brand logo on the left with the navbar-collapse menu and some other call to action/link above it on the right, and have them all vertically positioned.
Seems straight forward, until you want the mobile to look like this:
How can we achieve this with good responsive css (no negative margins/absolute positioning techniques) and no JS?
I've only come up with the option of printing the Phone number twice on the page, and hiding/showing for various screen sizes:
<header>
<div class="content-above-navbar container">
<div class="row d-md-none flex-row-reverse">
<div class="col-auto ml-3"><span class="navbar-text">800-BS4-WEBS</span></div>
<div class="col-auto p-0"><span class="navbar-text"><a href="#">Contact Us</a></span></div>
</div>
</div>
<nav class="navbar navbar-expand-md navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="Bootstrap 4 Navbar">Bootstrap 4 Navbar</a>
<button class="navbar-toggler collapsed" type="button" data-toggle="collapse" data-target="#all-pages-176" aria-controls="all-pages-176" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button>
<div id="all-pages-176" class="navbar-collapse has-content-above collapse">
<div class="content-above-nav-menu">
<div class="float-md-right ml-md-3 d-none d-md-block"><span class="navbar-text">800-BS4-WEBS</span></div>
<div class="float-md-right d-none d-md-block"><span class="navbar-text"><a href="#">Contact Us</a></span></div>
</div>
<ul id="menu-all-pages" class="navbar-nav ml-auto">
<li id="menu-item-1700" class="nav-item active"><a href="/sample-page/" class="nav-link active">Sample Page</a></li>
<li id="menu-item-1701" class="nav-item"><a href="/about/page-markup-and-formatting/" class="nav-link">Page Markup And Formatting</a></li>
<li id="menu-item-1702" class="nav-item"><a href="/about/page-image-alignment/" class="nav-link">Page Image Alignment</a></li>
<li id="menu-item-1705" class="nav-item"><a href="/level-1/" class="nav-link">Level 1</a></li>
</ul>
</div>
</div>
</nav>
</header>
There's a tiny bit of custom css to make the non-menu info stack up a row and move to the right. See the fiddle link:
Other markups work for one screen size, but not the other.
Is anybody seeing a solution to this that can be achieved w/ a relatively flat markup?
Upvotes: 1
Views: 1909
Reputation: 362820
It can be done with the Bootstrap 4 grid and utility classes...
Demo: https://www.codeply.com/go/CBsBPCE4oV
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<div class="row w-100 no-gutters d-lg-block d-flex flex-wrap justify-content-between">
<a class="navbar-brand col-lg-3 col-6 py-lg-3 order-lg-1 order-2 float-left d-block h-100" href="Bootstrap 4 Navbar">
Logo
</a>
<div class="navbar-text col-lg-6 col-12 order-lg-2 order-1 text-right float-right align-self-end">800-BS4-WEBS</div>
<button class="navbar-toggler collapsed float-right order-3" type="button" data-toggle="collapse" data-target="#all-pages-176" aria-controls="all-pages-176" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="all-pages-176" class="navbar-collapse collapse float-right col-lg-8 order-4">
<ul id="menu-all-pages" class="navbar-nav ml-auto justify-content-lg-end w-100">
<li id="menu-item-1700" class="nav-item active"><a href="/sample-page/" class="nav-link active">Sample Page</a></li>
<li id="menu-item-1701" class="nav-item"><a href="/about/page-markup-and-formatting/" class="nav-link">Page Markup And Formatting</a></li>
<li id="menu-item-1702" class="nav-item"><a href="/about/page-image-alignment/" class="nav-link">Page Image Alignment</a></li>
<li id="menu-item-1705" class="nav-item"><a href="/level-1/" class="nav-link">Level 1</a></li>
</ul>
</div>
</div>
</div>
</nav>
Upvotes: 1
Reputation: 1271
Echoing Raphael's comment to your question, I'm not entirely sure if the issue could be solved using Bootstrap's styles (other than with duplication of content, as you've shown).
Ignoring Bootstrap, if you only need to support IE11+ then CSS Grid can be used to achieve the layout you've described. I don't have enough experience with Bootstrap to know how well this solution would play with Bootstrap's styles, but here's a barebones example of your layout implemented with pure CSS grids (supporting IE would require adding additional styles that I left out for brevity):
.header {
margin: 1em;
padding: 1em;
display: grid;
grid-template-rows: auto auto;
grid-template-columns: 1fr auto;
grid-template-areas:
"c c"
"l t"
}
.header__logo {
grid-area: l;
}
.header__contact {
grid-area: c;
justify-self: end;
}
.header__menu {
display: none;
}
.header__toggle {
grid-area: t;
margin-left: 1em;
align-self: center;
}
@media (min-width:768px) {
.header {
grid-template-rows: auto auto;
grid-template-columns: auto 1fr;
grid-template-areas:
"l c"
"l m"
}
.header__toggle {
display: none;
}
.header__contact {
align-self: center;
}
.header__menu {
display: flex;
grid-area: m;
align-self: center;
justify-self: end;
}
}
/* debug styles */
.header {
border: 1px solid red;
}
.header > * {
outline: 1px dashed #cf0;
}
<div class="header">
<a href="#" class="header__logo"><img src="http://via.placeholder.com/200x80&text=Brand+Logo"/></a>
<div class="header__contact">
Contact Us <a href="#">800-BS4-WEBS</a>
</div>
<button class="header__toggle">=</button>
<div class="header__menu">
<a href="#">Sample Page</a>
<a href="#">Another Page</a>
</div>
</div>
Upvotes: 1