There are a couple of ways you can do this.
- Javascript, of course.
- Pure HTML
- Framework-like alternatives
For pure HTML solutions you can consider some very complex setups like sibling selectors:
html,
body {
height: 100%;
margin: 0;
background: darkgrey;
}
nav {
display: inline-block;
height: 100%;
width: 20%;
overflow-y: auto;
background: rgba(0, 0, 0, 0.5);
}
nav ul {
list-style: none;
padding: 0;
width: 100%;
text-indent: 20px;
color: white;
}
nav ul li {
width: 100%;
height: 40px;
}
nav ul li label {
display: inline-block;
float: left;
color: #FFF;
width: 100%;
height: 100%;
line-height: 40px;
cursor: pointer;
}
nav ul li:hover { background: grey; }
article {
display: none;
position: absolute;
height: 100%;
width: 80%;
}
input[type="radio"] { display: none; }
input[type="radio"]:checked+article {
display: inline-block;
}
<nav>
<ul>
<li><label for="article1">1</label></li>
<li><label for="article2">2</label></li>
<li><label for="article3">3</label></li>
<li><label for="article4">4</label></li>
<li><label for="article5">5</label></li>
<li><label for="article6">6</label></li>
<li><label for="article7">7</label></li>
<li><label for="article8">8</label></li>
<li><label for="article9">9</label></li>
<li><label for="article10">10</label></li>
<li><label for="article11">11</label></li>
<li><label for="article12">12</label></li>
<li><label for="article13">13</label></li>
<li><label for="article14">14</label></li>
<li><label for="article15">15</label></li>
<li><label for="article16">16</label></li>
<li><label for="article17">17</label></li>
<li><label for="article18">18</label></li>
<li><label for="article19">19</label></li>
<li><label for="article20">20</label></li>
</ul>
</nav>
<input type="radio" name="hacky" id="article1" />
<article>
<p>This is article 1. I am like all the other articles, but I am #1.</p>
</article>
<input type="radio" name="hacky" id="article2" />
<article>
<p>This is article 2. I am like all the other articles, but I am #2.</p>
</article>
<input type="radio" name="hacky" id="article3" />
<article>
<p>This is article 3. I am like all the other articles, but I am #3.</p>
</article>
<input type="radio" name="hacky" id="article4" />
<article>
<p>This is article 4. I am like all the other articles, but I am #4.</p>
</article>
<input type="radio" name="hacky" id="article5" />
<article>
<p>This is article 5. I am like all the other articles, but I am #5.</p>
</article>
<input type="radio" name="hacky" id="article6" />
<article>
<p>This is article 6. I am like all the other articles, but I am #6.</p>
</article>
<input type="radio" name="hacky" id="article7" />
<article>
<p>This is article 7. I am like all the other articles, but I am #7.</p>
</article>
<input type="radio" name="hacky" id="article8" />
<article>
<p>This is article 8. I am like all the other articles, but I am #8.</p>
</article>
<input type="radio" name="hacky" id="article9" />
<article>
<p>This is article 9. I am like all the other articles, but I am #9.</p>
</article>
<input type="radio" name="hacky" id="article10" />
<article>
<p>This is article 10. I am like all the other articles, but I am #10.</p>
</article>
<input type="radio" name="hacky" id="article11" />
<article>
<p>This is article 11. I am like all the other articles, but I am #11.</p>
</article>
<input type="radio" name="hacky" id="article12" />
<article>
<p>This is article 12. I am like all the other articles, but I am #12.</p>
</article>
<input type="radio" name="hacky" id="article13" />
<article>
<p>This is article 13. I am like all the other articles, but I am #13.</p>
</article>
<input type="radio" name="hacky" id="article14" />
<article>
<p>This is article 14. I am like all the other articles, but I am #14.</p>
</article>
<input type="radio" name="hacky" id="article15" />
<article>
<p>This is article 15. I am like all the other articles, but I am #15.</p>
</article>
<input type="radio" name="hacky" id="article16" />
<article>
<p>This is article 16. I am like all the other articles, but I am #16.</p>
</article>
<input type="radio" name="hacky" id="article17" />
<article>
<p>This is article 17. I am like all the other articles, but I am #17.</p>
</article>
<input type="radio" name="hacky" id="article18" />
<article>
<p>This is article 18. I am like all the other articles, but I am #18.</p>
</article>
<input type="radio" name="hacky" id="article19" />
<article>
<p>This is article 19. I am like all the other articles, but I am #19.</p>
</article>
<input type="radio" name="hacky" id="article20" />
<article>
<p>This is article 20. I am like all the other articles, but I am #20.</p>
</article>
Or you can consider the :target psuedo-class, which is a litter cleaner than the previous example and allows for a more semantically correct markup, but has some downsides like accessibility concerns in some respects. This solution also requires you to have an identifier for everything, not the end of the world but a disclaimer nonetheless:
section {
display: none;
background-color: lightseagreen;
color: white;
}
aside {
background-color: #ccc;
display: inline-flex;
}
section:target {
display: inline-flex;
}
<aside>
<ol>
<li><a href="#s1">Show the first section!</a></li>
<li><a href="#s2">Show the second section!</a></li>
<li><a href="#s3">Show the third section!</a></li>
<li><a href="#s4">Show the fourth section!</a></li>
</ol>
</aside>
<section id="s1">
<p>Hello! I am section #1</p>
</section>
<section id="s2">
<p>Hello! I am section #2</p>
</section>
<section id="s3">
<p>Hello! I am section #3</p>
</section>
<section id="s4">
<p>Hello! I am section #4</p>
</section>
Lastly, you can consider frameworks like Vue, Angular, React or PHP as mentioned. Since they weren't tagged in the OP, I assume it's out of scope and you are already aware of them.
There is something called ftHTML which only requires nodejs and is a little more focused on the HTML side of development.
Once it's installed, all you would need to do is make a file you can import and it will automatically be imported. Effectively, writing once, using everywhere.
Let's say you have a file called 'header' located in an 'imports' folder with that contains your header with links:
header
{
nav {
ul {
li "Home"
li "About"
}
}
}
You could write that once and then simply import it into other files:
doctype 'html'
html
{
head {
title "Home"
}
body {
import "./imports/header"
main
{
h1 "Hello World from Home page"
}
}
}
Then once you compile it to HTML it will produce something similar to the following for all your pages:
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
<header>
<nav>
<ul>
<li>Home</li>
<li>About</li>
</ul>
</nav>
</header>
<main>
<h1>Hello World from Home page</h1>
</main>
</body>
</html>
Disclaimer; I am the author of ftHTML