Navigating through <nav>, <section>, and <main> elements

I have the ability to split the entire page into four regions, which are:

[header] (at the very top), [nav] (located directly below the header), [section] (bottom left), and [main] (bottom right).

The [nav] section contains a list of hyperlinked items (such as "item-A", "item-B", etc).

The objective is as follows:

When "item-A" is chosen, the corresponding sub-list containing "A1", "A2", "A3", and so on should be displayed in the [section] region. Likewise, if "item-B" is selected, the sub-list "B1", "B2" should replace the previous content and be shown in the [section] area.

"B2" is linked to the file "B.html, which, when accessed, should run in the [main] section.

How can I achieve all of the above?

P.S. While I can accomplish this using [frame] and [frameset], these elements are considered outdated in HTML5.

https://i.sstatic.net/b9P0d.png

The widths and heights of each region can be specified within the CSS configuration.

Answer №1

You have the option to utilize buttons instead of hyperlinks to achieve the same desired outcome.

Here is the solution I propose:

const displayItemA = () => {
    document.getElementById("item-A").style.display = 'grid';
    document.getElementById("item-B").style.display = 'none';
}
const displayItemB = () => {
    document.getElementById("item-B").style.display = 'grid';
    document.getElementById("item-A").style.display = 'none';
}

const mainContent = ["A1", "A2", "A3", "B1", "B2", "B3"];
const displayMain = (q) => {
    document.getElementById(q).style.display = "grid";
    const toNone = mainContent.filter(e => e !== q);
    for (let i = 0; i < toNone.length; i++) {
        document.getElementById(toNone[i]).style.display = "none";
    }
}

const displayA1 = () => displayMain("A1");
const displayA2 = () => displayMain("A2");
const displayA3 = () => displayMain("A3");
const displayB1 = () => displayMain("B1");
const displayB2 = () => displayMain("B2");
const displayB3 = () => displayMain("B3");
:root {
--main-color:red;
--dark-color:#444;
}
* {
margin:0;
padding:0;
box-sizing:border-box;
}
body {
margin: 0px;
display: grid;
place-items: center;
font-size: 20px;
}

/* repeated element */
.button-nav {
    text-decoration: none;
    color: var(--main-color);
    background: none;
    border: none;
    font-size: 20px;
    text-align: start;
}

.header {
    height: 100px;
    width: 100%;
    display: grid;
    place-items: center;
    border-bottom: 2px solid var(--dark-color);
}

.nav {
    position: relative;
    height: 75px;
    width: 100%;
    border-bottom: 2px solid var(--dark-color);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1em;
}
.nav h2 {
    position: absolute;
    left: 30px;
}

.section {
    position: absolute;
    left: 0px;
    min-height: calc(100vh - 175px);
    width: 30%;
    border-right: 2px solid var(--dark-color);
    padding: 30px;
    gap: 1em;
}
.sub-nav {
    display: grid;
    gap: 1em;
}
#item-A, #item-B{ display:none }

.main {
    position: absolute;
    left: 30%;
    min-height: calc(100vh - 175px);
    width: 70%;
    display: grid;
    padding: 30px;
    gap: 1em;
    text-align: center;
}
#A1 { display: grid; }
#A2, #A3, #B1, #B2, #B3 { display: none; }
<header class="header">
        <h1>Header</h1>
    </header>
    <nav class="nav">
        <h2>Nav</h2>
        <button class="button-nav" onclick="displayItemA()">item-A</button>
        <button class="button-nav" onclick="displayItemB()">item-B</button>
    </nav>
    <div>
        <section class="section">
            <h3>Section</h3>
            <br />
            <nav class="sub-nav" id="item-A">
                <button class="button-nav" onclick="displayA1()">A1</button>
                <button class="button-nav" onclick="displayA2()">A2</button>
                <button class="button-nav" onclick="displayA3()">A3</button>
            </nav>
            <nav class="sub-nav" id="item-B">
                <button class="button-nav" onclick="displayB1()">B1</button>
                <button class="button-nav" onclick="displayB2()">B2</button>
                <button class="button-nav" onclick="displayB3()">B3</button>
            </nav>
        </section>
        <main class="main">
            <h3>Main</h3>
            <div id="A1">These are the contents of A1.</div>
            <div id="A2">These are the contents of A2.</div>
            <div id="A3">These are the contents of A3.</div>
            <div id="B1">These are the contents of B1.</div>
            <div id="B2">These are the contents of B2.</div>
            <div id="B3">These are the contents of B3.</div>
        </main>
    </div>

Feel free to test out the code by clicking on this link here to see it in action within a larger viewport.

Update: In response to the OP's request, the items in the "section" area have been set blank by default. This was achieved by adjusting the value of the display property for "#item-A" to "none" in the CSS file.

Answer №2

Check out the Stack Blitz code: https://stackblitz.com/edit/web-platform-uwbmw4?devtoolsheight=33&file=index.html


In order to function correctly, this code requires a1, a2, b1, b2 HTML files and additional resources that may not work below (the iframe components are excluded). Please test it using the provided Stack Blitz link above.

const itemAOptions = [
  {
    name: 'A1',
    data: 'A1.html',
  },
  {
    name: 'A2',
    data: 'A2.html',
  },
];

const itemBOptions = [
  {
    name: 'B1',
    data: 'B1.html',
  },
  {
    name: 'B2',
    data: 'B2.html',
  },
];

const dataContainer = document.querySelector('#display');
const menuContainer = document.querySelector('#menu');
const navContainer = document.querySelector('#navBar');

navContainer.addEventListener('click', (e) => {
  e.stopPropagation();
  if ('nochange' in e.target.dataset) {
    e.preventDefault();
    const toLoad = e.target.dataset.nochange;
    let data = '';
    if (toLoad === 'loadA') {
      data = constructData(itemAOptions);
    } else {
      data = constructData(itemBOptions);
    }
    menuContainer.innerHTML = data;
    display.innerHTML = ``;//emptydata means clear or empty screen as you requested
  }
});

menuContainer.addEventListener('click', (e) => {
  e.stopPropagation();

  e.preventDefault();
  const toLoad = e.target;
  let data = '';

  data = `<iframe src="https://web-platform-uwbmw4.stackblitz.io/${toLoad.innerHTML}.html" name="targetframe" allowTransparency="true" scrolling="no" frameborder="0" >
      </iframe>`;//use src="Your.Website.address.or.directory/${toLoad.innerHTML}.html"

  console.log(toLoad.innerHTML);
  display.innerHTML = data;
});

function constructData(item) {
  let innerData = '';
  item.forEach((i) => {
    innerData += `<li class="li"><a href=# class="a">${i.name}</a></li>`;
  });
  return `<ul class="ul">${innerData}</ul>`;
}

function constructDataIframe(item) {
  let innerData = '';
  item.forEach((i) => {
    innerData += `<iframe src="https://web-platform-uwbmw4.stackblitz.io/${i.data}" name="targetframe" allowTransparency="true" scrolling="no" frameborder="0" >
    </iframe>`;
  });
  return `${innerData}`;
}
h1 {
  text-align:center;
}
#navBar{
  background-color: transparent;
  border: 5px solid black;
  text-align: center;
}
.lk{
  text-decoration: none;
}
.uli{
  display: flex;
  justify-content: flex-end;
}
.lik{
  list-style: none;
  padding-right:15px;
}
.a{
  text-decoration: none;
}
.li{
  list-style: none;

}
.ul{
  float:left;
  padding-left: 10px;
}
#secHolder{
  width: 100%;
  background-color: transparent;
  border: 5px solid black;
  text-align: center;
}

#display{
  width: 100%;
  background-color: transparent;
  border: 5px solid black;
  text-align: center;
}
#Holder{
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: center;
}
<html>
  <head>
    <meta charset="UTF-8">
    
    <link rel="stylesheet" type="text/css" href="styles.css"> 
  </head>
  <body>
   <h1>Header</h1>
  <nav id="navBar">
  
  <ul>
    <div class="uli">
    <li class="lik"><a href="#" data-nochange="loadA" class="lk">Item A</a></li>
    <li class="lik"><a href="#" data-nochange="loadB" class="lk">Item B</a></li>
  </div>
  </ul>
</nav>
<div id="Holder">

<div id="secHolder">
<h3>Section</h3>
<section id="menu"></section>
</div>
<main id="display"></main>
</div>
<script src="script.js"></script>
  </body>
</html>

https://i.sstatic.net/JWlCh.png

P.S I have tried my best on answering but I don't have regular practice on commenting please try to understand, ask for doubts.

I cannot understand what you mean by

I cannot use frame its obsolete in html5
, I have used iframe is it ok?

Answer №3

I didn't focus much on styling, but it's better to consider using iframes instead of object tags. You might want to explore that option as well.

const itemAOptions = [{
  name:"A1",
  data:"A1.html"
}, {
  name:"A2",
  data:"A2.html"
}];

const itemBOptions = [{
  name:"B1",
  data:"B1.html"
}, {
  name:"B2",
  data:"B2.html"
}];

const dataContainer = document.querySelector("#display");
const menuContainer = document.querySelector("#menu");
const navContainer = document.querySelector("#navBar");

navContainer.addEventListener("click", (e)=>{
  e.stopPropagation();
  if("nochange" in e.target.dataset){
    e.preventDefault();
    const toLoad = e.target.dataset.nochange;
    let data = '';
    if(toLoad === "loadA"){
      data = constructData(itemAOptions);
    }
    else{
      data = constructData(itemBOptions);
    }
    menuContainer.innerHTML = data;
  }
});

menuContainer.addEventListener("click", (e)=>{
  e.stopPropagation();
  if("spaload" in e.target.dataset){
    e.preventDefault();
    const data = e.target.dataset.spaload;
    dataContainer.innerHTML=`<object type="text/html" data=${data} ></object>`;
  }
});

function constructData(item){
  let innerData = '';
  item.forEach((i)=>{
    innerData+=`<li><a href=${i.data} data-spaload=${i.data}>${i.name}</a></li>`;
  });
  return `<ul>${innerData}</ul>`;
}
<nav id="navBar">
  <ul>
    <li><a href="#" data-nochange="loadA">Item A</a></li>
    <li><a href="#" data-nochange="loadB">Item B</a></li>
  </ul>
</nav>
<h3>Section</h3>
<section id="menu"></section>
<main id="display"></main>

Answer №4

const embed = document.getElementById("main-frame");
const navLinksContainer = document.getElementById("nav-links");
const subLinksContainer = document.getElementById("sub-links");

const pageLinks = {
  "item-A": {
    A1: "https://en.wikipedia.org/wiki/Australia",
    A2: "https://en.wikipedia.org/wiki/Austria",
    A3: "https://en.wikipedia.org/wiki/America",
  },
  "item-B": {
    B1: "https://en.wikipedia.org/wiki/Barbados",
    B2: "https://en.wikipedia.org/wiki/Bahamas",
    B3: "https://en.wikipedia.org/wiki/Brazil",
  },
  "item-C": {
    C1: "https://en.wikipedia.org/wiki/Canada",
    C2: "https://en.wikipedia.org/wiki/Cayman_Islands",
    C3: "https://en.wikipedia.org/wiki/Chile",
  },
};

// Function to create a link element for the page
function createPageLink(text, href = "") {
  const listItem = document.createElement("LI");
  const anchor = document.createElement("A");
  anchor.innerHTML = text;
  anchor.href = href;
  listItem.appendChild(anchor);
  listItem.anchor = anchor;
  return listItem;
}

window.onload = function loadHandler() {
  // Generating sub links for each navigation link.
  Object.keys(pageLinks).forEach((text) => {
    const subSectionLinks = Object.keys(pageLinks[text]).map((subText) => {
      const subLink = createPageLink(subText, pageLinks[text][subText]);
      subLink.anchor.addEventListener("click", function (event) {
        event.preventDefault();
        embed.src = event.target.href;
      });
      return subLink;
    });

    // Replacing the existing sub links when a navigation link is clicked.
    const navLink = createPageLink(text);
    navLink.anchor.addEventListener("click", function (event) {
      event.preventDefault();
      subLinksContainer.innerHTML = "";
      subSectionLinks.forEach((element) =>
        subLinksContainer.appendChild(element)
      );
      embed.src = "";
    });
    navLinksContainer.appendChild(navLink);
  });
};
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

ul {
  list-style-type: none;
}

a {
  text-decoration: none;
  color: red;
  font-size: 28px;
}

a:hover {
  color: #920000;
}

body {
  font-family: Arial, Helvetica, sans-serif;
  font-weight: bold;
  font-size: 32px;
  color: #222;
}

.page {
  width: 702px;
  height: 918px;
  margin: 50px auto;
  display: grid;
  gap: 0;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(10, 1fr);
  grid-template-areas:
    "h h h h"
    "h h h h"
    "n n n n"
    "s m m m"
    "s m m m"
    "s m m m"
    "s m m m"
    "s m m m"
    "s m m m"
    "s m m m";
}

.page > * {
  border: 1px solid #777;
}

.page > header {
  grid-area: h;
  display: flex;
  justify-content: center;
  align-items: center;
}

.page > nav {
  grid-area: n;
  display: flex;
  flex-direction: row;
  align-items: center;
}

.page > section {
  grid-area: s;
  text-align: center;
  padding-top: 15px;
}

.page > main {
  grid-area: m;
  text-align: center;
}

.page > nav div {
  width: 25%;
  text-align: center;
}

.page > nav ul {
  width: calc(100% - 25%);
  text-align: center;
}

.page > nav ul li {
  display: inline;
}

.page > nav ul li:nth-of-type(n + 2) {
  margin-left: 15px;
}

.page > section ul {
  margin-top: 50px;
  text-align: left;
  text-indent: 40px;
}

.page > section ul li {
  margin-bottom: 10px;
}

.page > main p {
  height: 8%;
  margin-top: 20px;
}

.page > main iframe {
  width: 100%;
  height: calc(92% - 20px);
  border: none;
  overflow-x: hidden;
}
<div class="page">
  <header>Header</header>

  <nav>
    <div>nav</div>
    <ul id="nav-links"></ul>
  </nav>

  <section>
    section
    <ul id="sub-links"></ul>
  </section>

  <main>
    <p>main</p>
    <iframe allowTransparency="true" id="main-frame"></iframe>
  </main>
</div>

Update:

I made modifications to the code in order to clear the iframe whenever a new link is selected from the navigation bar based on user feedback.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Change the color of the text in a shiny dashboard

While exploring shiny dashboard, I came across this link that explains how to modify colors in the sidebar and header. However, I'm struggling to change the font color for sidebar items. The default white font color becomes unreadable when using light ...

The arrangement of divs in a modern metropolitan aesthetic

I'm facing an issue with the positioning of the tiles div in metro u. This is specifically for SharePoint, so I can only work with CSS/HTML and not JavaScript. The problem seems to be a missing div on the left side. Any assistance would be greatly app ...

Arrange the element as though it were the foremost

My specific scenario is as follows: <div id="container"> <p id="first">...</p> <p id="second">...</p> </div> I am looking to rearrange the order of second and first within the HTML stru ...

Is there a way to move the bootstrap carousel item captions outside of the image without having to set a specific height for the carousel manually?

<div id="carouselExampleIndicators" className="carousel slide" data-bs-ride="true"> <div className="carousel-indicators"> <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0" className="active" ...

Creating a mobile-friendly table using Bootstrap 4 and CSS: A step-by-step guide

Looking to create a responsive table? I've got my table ready for desktop view, but now I want it to display properly on smartphones too. Here's how my table looks on the website: https://i.sstatic.net/zMXQo.png and here's the code I&apos ...

Activate the Bootstrap 5 responsive font sizing feature (RFS) for the base font elements

I'm attempting to utilize Bootstrap's RFS functionality in version 5.1.3 to apply font sizing globally. Within my SCSS file, I've defined some basic font sizes, imported the Bootstrap SCSS files, and configured the font size settings. Howev ...

Stop the CSS animation on the circular menu to toggle it open and closed

I have a circular menu with the added code "animation: pulse infinite". The menu can be opened and dragged around. Now, I want to add a pause animation so that it stops for a while when the menu is opened and closed. I tried adding "animation-play-state" ...

Creating an Image Slideshow on Your Website

I'm looking to create an image slideshow on my website that functions similarly to the one found at . However, I want the images to occupy the entire screen rather than having smaller images like the reference site. Can anyone offer guidance on how t ...

custard stealth style of jquery's mobile CSS

Is there a way to switch the jquery mobile CSS to a desktop-friendly CSS when a user is not on a mobile device? I am looking for a platform or existing CSS that can accomplish this. ...

Ways to position two images in the center

A website has been created by me and now I am looking to center text on the two images in the header. Here is the relevant code snippet: <div class="header"> <img src="css/title578145459.png" class="headerImage left&qu ...

Enhancing the appearance of h3 headings using CSS without changing the HTML code

I'm looking to add some style to the h2 elements on my website. Here is an example of a website where I like the styling: Another reference site for comparison is: If you look at the first h3 heading that reads "Head To Head Comparison Between Merge ...

Why doesn't "align-self: flex-end" relocate the game board to the bottom of the screen?

Hey there, I am currently working on developing a Connect 4 game and have decided to use a table for the board. To position the board properly, I am utilizing flexbox. Although I have specified align-items as 'flex-end' in order to bring it to th ...

How to position a full-width banner image in the center using CSS without causing scrollbars

I am facing a design challenge with my webpage where the content is 1000px wide. In the middle of this page, I want to showcase an image that is 600px high and 2000px wide. The tricky part is ensuring that this image remains 600px high, maintains its aspe ...

Chrome does not display the play button when the width of the audio tag is reduced in HTML 5

I'm looking to implement the HTML 5 audio tag that works on both Chrome and Firefox: <audio controls preload="metadata" style=" width:50px; border-radius: 100px;margin-top: 15px; float: left;"> <source src="https://s4.uuploa ...

Putting a link on a button exclusively

Currently, I am utilizing Bootstrap 5 to develop a website. One of the pages features a header that consists of an image with text and a button overlay. The intended functionality is for users to be redirected to another site when clicking on the button. ...

Is it possible to dynamically load a specific div when the page loads, relying on the

I am using JQuery SlideUp and slideDown methods to toggle the visibility of panels. How can I load or display the first record's contact information as a default? Currently, it loads blank because I set the panel's display property to none: < ...

Issues with CSS positioning are not being resolved in Chrome

I set up a Wordpress website and I'm trying to display two vertical banners outside of the main container. My CSS code seems to work fine on Firefox and IE, but on Chrome only the left banner is showing up. Any suggestions on what might be causing thi ...

Utilize a dual-color gradient effect on separate words within the <li> element

I am attempting to display the fizz buzz function in an unordered list, with each word being a different color ('fizz'-- green, 'buzz'--blue) as shown here: https://i.sstatic.net/Yvdal.jpg I have successfully displayed "fizz" and "buz ...

When adjusting the browser size, I must minimize the spacing between the headings

I have tried the following code, but when I resize the browser, the space between the two headings for the tab view doesn't work as expected. I want the texts to be displayed without any space when I resize the browser. Below is the HTML and CSS code ...

Maintain the grouping of elements within a div when printing in Internet Explorer 8

When printing in IE8, I'm facing an issue with keeping the "Table title" line on the same page as the <table>. Despite using page-break-inside:avoid;, there is still a page break between the table title and the actual table. My expectation is f ...