#12 Main Navigation (Anchors)
Saturday, January 5, 2019
In this article we are going to create the main anchor tags for our top navigation bar. Once they are defined we will of course apply some styling to make them fit in with the overall feel of our header. Probably the most important step of the this process is we will mimic the mixin ability of templating languages like pug to allow us to write the markup for the anchors once and have them displayed in different locations. This will be important for us since we are working to create a responsive navigation bar that will work with any form factor from desktop to mobile.
Parts
- Part 29: Offset Pager Urls
- Part 28: Offset Pager Start
- Part 27: Mock Context Builder
- Part 26: Mock Repository
- Part 25: Mock Async
- Part 24: Picture Tag Helper
- Part 23: Img DPR Tag Helper
- Part 22: Img Responsive Tag Helper
- Part 21: Img Optimized Display
- Part 20: Img Optimization
- Part 19: Img Lazy Loading
- Part 18: Img Responsive
- Part 17: Bottom Nav
- Part 16: Main Nav Cookie
- Part 15: Main Nav Mobile
- Part 14: Main Nav Search
- Part 13: Main Nav Auth
- Part 12: Main Nav Anchors
- Part 11: Main Nav Logo
- Part 10: Search Results
- Part 9: Search Manager
- Part 8: Search Start
- Part 7: Seeding the Database
- Part 6: Domain Database
- Part 5: Emailing Exceptions
- Part 4: Mailkit
- Part 3: View Renderer
- Part 2: Upgrade to 2.1
- Part 1: Quick Start
Any good app needs icons
- WebUi
- package.json
The first thing we are going to do is to add the ability for us to add icons to our main navigation by installing a couple of fontawesome npm packages using the command shown in (a). The version numbers for these packages at the time of the writing of this article are shown in (b).
Terminal
npm install --save-dev @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons
package.json
{
...
"devDependencies": {
"@fortawesome/free-solid-svg-icons": "^5.5.0",
"@fortawesome/fontawesome-svg-core": "^1.2.8",
...
}
}
Adding the icons to the page
- WebUi
- Source
- main.site.ts
- Source
The way that font awesome works is we will place some tags on our pages with the appropriate css classes and they will get parsed and replaced by their svg counterparts. To do this we need to add just a little bit of javascript to our pages. To make things a bit simpler on us we will include the javascript code in each of our pages by adding it to our main bundle (c).
main.site.ts
if (process.env.NODE_ENV === "development" && module.hot) {
module.hot.accept();
}
import { dom, library } from "@fortawesome/fontawesome-svg-core";
import { faBars } from "@fortawesome/free-solid-svg-icons/faBars";
library.add(faBars);
dom.watch();
The main navigation anchors
- WebUi
- Pages
- Shared
- _MainNav.cshtml
- Shared
- Pages
Next it is time to add some anchor tags to our main navigation which will allow our users to easily access the main content of our site (d). In the end we will want to have these anchors placed in both the main and mobile navigation areas. We could of course just copy and paste them but where is the fun in that. But for now we will just hard code them here so that we have something to style.
_MainNav.cshtml
@{
const string cssLinkAnchor = "link-anchor";
const string cssLinkText = "link-text";
}
<header>
<nav class="main-navigation">
...
<div class="anchors">
<ul class="anchors-lg">
<li class="link">
<a href="/articles/page-1" class="@cssLinkAnchor">
<div class="@cssLinkText">
<span>Articles</span>
</div>
</a>
</li>
<li class="link">
<a href="/applications/page-1" class="@cssLinkAnchor">
<div class="@cssLinkText">
<span>Applications</span>
</div>
</a>
</li>
</ul>
<div class="anchor-bars">
<a id="mobile-toggle">
<div class="@cssLinkText">
<i class="fas fa-bars fa-lg"></i>
</div>
</a>
</div>
</div>
</nav>
</header>
Speaking of styling
- WebUi
- Source
- components
- main-nav
- main-nav.component.scss
- main-nav
- components
- Source
With the anchors added to the navigation menu we can now add some styling (e).
main-nav.component.scss
...
header {
...
ul {
display: flex;
flex-direction: row;
height: 100%;
margin: 0;
padding: 0;
}
li {
height: 100%;
}
.main-navigation {
...
grid-template-areas: "logo anchors";
grid-template-columns: auto 1fr;
...
@include media-gt($mobile-break-width) {
grid-template-areas: "logo anchors";
grid-template-columns: auto 1fr;
}
}
...
.anchors {
grid-area: anchors;
.anchors-lg {
display: none;
@include media-gt($mobile-break-width) {
display: flex;
}
}
.anchor-bars {
height: 100%;
@include media-gt($mobile-break-width) {
display: none;
}
a {
@include padding(null em(16px));
cursor: pointer;
}
}
}
}
Mimicking the mixin capability of pug
- WebUi
- Pages
- Shared
- _MainNav.cshtml
- Shared
- Pages
As I mentioned previously we are going to want to have the same anchor tags placed in two different locations and that we could just copy and paste them but that was not what we were going to do. Initially I created the header and main navigation in angular which meant that I could write the markup in a templating language which for this instance was pug. When the template was written in pug I could just create a few mixins to have the ability to write once and place the same content in multiple different locations. In this case using the fact that we have access to razor syntax we can accomplish pretty much the same thing using a few local functions (f).
_MainNav.cshtml
@using Microsoft.AspNetCore.Html
@{
...
var LinkText = new Func<string, string>((text) => $"<div class=\"{cssLinkText}\"><span>{text}</span></div>");
var Anchor = new Func<string, string, string>((href, block) => $"<a href=\"{href}\" class=\"{cssLinkAnchor}\">{block}</a>");
var Li = new Func<string, string>((block) => $"<li class=\"link\">{block}</li>");
var Articles = Html.Raw(Li(Anchor("/articles/page-1", LinkText("Articles"))));
var Applications = Html.Raw(Li(Anchor("/applications/page-1", LinkText("Applications"))));
var Videos = Html.Raw(Li($"<a class=\"{cssLinkAnchor}\" href=\"https://www.youtube.com/c/excitoninteractivellc\" target=\"_blank\" rel=\"noreferrer\">Videos</a>"));
}
header {
...
<div class="anchors">
<ul class="anchors-lg">
@Articles
@Applications
@Videos
</ul>
...
</div>
}