Responsive Navigation without duplicate links? - javascript

Recently I've been attempting to make my own responsive navigation and have managed to, but now i'm wanting to jump the next hurdle, which is to create the same navigation but without having two seperate link lists.
Now I've tried various methods to get this to work, including using javascript to add / remove classes when at a certain width, which worked to a certain extent, but only if i resized the browser for it to find out the browser width, which obviously has it's flaws when you can't resize the browser when on a mobile device.
The code i've currently got is -
HTML
<nav class="mainnav" role="navigation">
<div class="desktopnav" id="navigation">
<ul class="mainlinks">
<li role="menuitem">Home</li>
<li role="menuitem">About</li>
<li role="menuitem">My Work</li>
<li role="menuitem">Contact</li>
</ul>
</div>
<div class="mobilenav">
<button class="navtoggle">toggle</button>
<ul class="mainlinks">
<li role="menuitem">Home</li>
<li role="menuitem">About</li>
<li role="menuitem">My Work</li>
<li role="menuitem">Contact</li>
</ul>
</div>
</nav>
CSS
.mainnav {
width: 100%;
height: auto;
background: #64137B; }
/*Desktop nav*/
.desktopnav {
display: block; }
.desktopnav ul.mainlinks {
list-style-type: none;
margin: 0 auto;
padding: 0;
display: table;
min-height: 50px; }
.desktopnav ul.mainlinks li {
display: table-cell;
vertical-align: middle;
text-align: center;
padding: 10px;
border-right: 1px solid #A37EAE; }
.desktopnav ul.mainlinks li:first-child {
border-left: 1px solid #A37EAE; }
.desktopnav ul.mainlinks a {
color: white;
text-decoration: none; }
.mobilenav, .desktopnav {
min-height: 50px;
height: auto; }
/*Mobile Nav*/
.mobilenav {
text-align: center; }
.mobilenav, button.navtoggle {
display: none; }
.mobilenav ul.mainlinks {
display: none;
list-style: none;
padding-left: 0px; }
#media (max-width: 768px) {
.desktopnav {
display: none; }
.mobilenav {
display: block; }
button.navtoggle {
display: table-cell;
margin: 5px auto;
text-align: center;
border: 0;
text-indent: 200%;
overflow: hidden;
background: white url(../../images/navbutton.png) center no-repeat;
border: 1px solid #ddd;
border-radius: 5px;
background-size: 80%;
width: 40px;
height: 40px;
outline: none;
opacity: 1;
transition: opacity .25s ease-in-out;
-moz-transition: opacity .25s ease-in-out;
-webkit-transition: opacity .25s ease-in-out; }
button.navtoggle:hover {
opacity: 0.7; }
ul.mainlinks {
background: #8421A0;
margin: 0px;
padding: 0px 0px; }
ul.mainlinks li {
padding: 15px 10px;
border-bottom: 1px solid #A37EAE; }
ul.mainlinks a {
color: white;
text-decoration: none; }
}
Has anyone got any ideas on what i might be able to do, to fix my problem?
Thanks

You need to use media queries, that way you can set position values entirely based on the size of the screen:
.nav {
/* some common properties here */
/* some positioning properties here */
/* these will be set for everything and may need over-riding */
}
#media (min-width: 800px) {
.nav {
/* some completely different positioning properties here */
/* remember, some may be over-rides */
}
}
Declaring the common properties in a class then over-riding as the screen gets wider is basic mobile first best practice - it enables you to handle tough layout issues with room to expand, rather than getting everything perfect large and finding it's hard to squeeze down. In some cases, you may need to use a declaration like this:
#media (min-width: 480px) and (max-width: 800px) {
/* properties */
}

Related

How can I convert an already created sidebar into a responsive design?

The sidebar looks like the below snippet. What should i add to this code, like a wrapper to make it responsive in mobile screen?
.sidebar{
position: fixed;
left: 0px;
width: 314px;
height: 100vh;
background-color: #002438;
box-shadow: hsl(0, 0%, 75%) 7px 2px 15px;
}
.sidebar li{
margin-top: 45px;
font-size: 24px;
color: white;
text-align: center;
text-decoration: none;
}
.sidebar a{
color: white;
text-decoration: none;
}
.sidebar li :hover{
color: #00fff2;
}
.sidelist{
display: flex;
flex-direction: column;
padding-top: 20px;
margin-top: 40px;
text-align: center;
}
.active a{
width: 230px !important;
display: block;
margin: 10px auto;
font-weight: bold;
padding: 5px 10px;
border-radius: 50px;
background: #fff;
}
<div class="sidebar">
<ul class="sidelist">
<li>DASHBOARD</li>
<li class="active">CUSTOMER</li>
<li>LEADS</li>
<li>REPORTS</li>
<li>SMS</li>
<li>PROFILE</li>
</ul>
</div>
This is my sidebar. How do i turn it into a hamburger icon in mobile screens, which when clicked or dragged, moved from left to right side with all the sidebar.
What I might do is use a media query. If you want this to just be an icon button with the little hamburger icon, make the icon button above or below where you made this sidebar. In your css that you have there, give it another class maybe something like this:
.menuIcon {
display: 'none';
/* your other styles here */
}
Then the media query (you can make more than one) do something like this:
#media only screen and (max-width: 1000px) {
.menuIcon {
/* styles */
}
.sidebar {
display: 'none';
/* styles */
}
}
Of course change the media query to match what size screen you want to adjust for, and style how you want.

Close navigation when navigation item is clicked

My goal is for my hamburger menu to close when an item is clicked inside of it. As of right now, the menu only uses html and css.
The difference between this nav bar and others is that mine is created from a input checkbox html element, what i need is for my checkbox to uncheck when a link is clicked inside of the hamburger. This should close the entire menu just like it would if i clicked on the hamburger. Also, could you explain what and why the javascript does what it does, i don't have much experience with javascript, thanks. :)
I also made the checkbox visible just so that we can have a better understanding of whats going on.
My CSS:
/* navigation menu */
.nav {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 70px;
line-height: 70px;
text-align: right;
z-index: 10000;
background-color: #ffffff;
border-bottom: 1px solid #eaeaeb;
}
.menu {
margin: 0 30px 0 0;
}
/* link items */
.menu a {
clear: right;
line-height: 70px;
text-decoration: none;
margin: 0 10px;
text-align: center;
color: #33334d;
background-color: #ffffff;
}
.menu a:hover {
background-color: #c2c2d6;
}
/* hamburger properties */
label {
float: right;
display: none;
width: 26px;
line-height: 70px;
margin: 0 40px 0 0;
font-size: 36px;
}
/* checkbox */
#toggle {
}
#media only screen and (max-width: 1075px) {
/* hamburger properties */
label {
display: block;
cursor: pointer;
}
/* nav menu properties */
.menu {
width: 100%;
display: none;
text-align: center;
}
/* link items */
.menu a {
display: block;
margin: 0px;
border-bottom: 1px solid #eaeaeb;
}
/* makes links show when checkbox is checked */
#toggle:checked + .menu {
display: block;
}
}
My HTML:
<div class="nav">
<label for="toggle">☰</label>
<input type="checkbox" id="toggle"/>
<div class="menu">
example
example
example
example
example
example
example
</div>
</div>
Javscript may not actually be required, depending on your needs.
If you give the div containing your nav links an ID you can target this with an a tag setting the href to the ID. Then you can use the :target selector to change the visibility of our navigation div.
/* navigation menu */
.nav {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 70px;
line-height: 70px;
text-align: right;
z-index: 10000;
background-color: #ffffff;
border-bottom: 1px solid #eaeaeb;
}
.menu {
margin: 0 30px 0 0;
}
/* link items */
.menu a {
clear: right;
line-height: 70px;
text-decoration: none;
margin: 0 10px;
text-align: center;
color: #33334d;
background-color: #ffffff;
}
.toggle {
text-decoration: none;
color: #33334d;
}
.menu a:hover {
background-color: #c2c2d6;
}
/* hamburger properties */
.toggle,
label {
float: right;
display: none;
width: 26px;
line-height: 70px;
margin: 0 40px 0 0;
font-size: 36px;
}
/* checkbox */
#toggle {}
#media only screen and (max-width: 1075px) {
/* hamburger properties */
.toggle,
label {
display: block;
cursor: pointer;
}
/* nav menu properties */
.menu {
width: 100%;
display: none;
text-align: center;
}
/* link items */
.menu a {
display: block;
margin: 0px;
border-bottom: 1px solid #eaeaeb;
}
/* makes links show when checkbox is checked */
#menu:target,
#toggle:checked+.menu {
display: block;
}
}
<div class="nav">
<a class="toggle" href="#menu">☰</a>
<div class="menu" id="menu">
example
example
example
example
example
example
example
</div>
</div>
Wow, interesting. It's a pretty weird practise, what you have, but it could work. You can make menu show/hide by input checked. Very interesting. I have never think of like that.
But also you will need a piece of JS code.
By CSS you can handle some basic selector like :hover, :focus, :active etc. In our your case you also make some interesting click event. But checkbox is not for that purpose.
Click and other event are handled by JS (more https://www.w3schools.com/js/js_events.asp).
So in our case, we select all links:
var links = document.querySelectorAll('.menu a');
then we have to add click event to every link, which will set our input to checked="false" = close menu.
This JS code will only work, when selected links are rendered, so you need to put this piece of code to the end of your html file before </body> or use window.onload...
var links = document.querySelectorAll('.menu a');
var linksLength = links.length
for(var i = 0; i < linksLength; i++) {
links[i].addEventListener('click', function() {
document.getElementById('toggle').checked = false;
});
}
/* navigation menu */
.nav {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 70px;
line-height: 70px;
text-align: right;
z-index: 10000;
background-color: #ffffff;
border-bottom: 1px solid #eaeaeb;
}
.menu {
margin: 0 30px 0 0;
}
/* link items */
.menu a {
clear: right;
line-height: 70px;
text-decoration: none;
margin: 0 10px;
text-align: center;
color: #33334d;
background-color: #ffffff;
}
.menu a:hover {
background-color: #c2c2d6;
}
/* hamburger properties */
label {
float: right;
display: none;
width: 26px;
line-height: 70px;
margin: 0 40px 0 0;
font-size: 36px;
}
/* checkbox */
#toggle {
}
#media only screen and (max-width: 1075px) {
/* hamburger properties */
label {
display: block;
cursor: pointer;
}
/* nav menu properties */
.menu {
width: 100%;
display: none;
text-align: center;
}
/* link items */
.menu a {
display: block;
margin: 0px;
border-bottom: 1px solid #eaeaeb;
}
/* makes links show when checkbox is checked */
#toggle {
display: none;
}
#toggle:checked + .menu {
display: block;
}
}
<label class="nav" for="toggle">
<div class="icon">☰</div>
<input type="checkbox" id="toggle"/>
<div class="menu">
example
example
example
example
example
example
example
</div>
</label>

Responsive Navigation Not Showing All Items

Hello I am currently learning responsive design and I am trying to make a responsive navigation bar which turns in to a menu when visited on a phone or mobile device! Everything works except not all the navigation items show on the mobile device and I am not sure why! This is the code:
<div class="container">
<div class="navbar">
<ul style="padding-left: 0px;">
<li class="logo"> RONNIE<b>GURR</b></li>
<section class="div_navbar_items">
<li class="navbar_items"> HOME </li>
<li class="navbar_items"> ABOUT US </li>
<li class="navbar_items"> GALLERY </li>
<li class="navbar_items"> SHOP </li>
<li class="navbar_items"> CONTACT </li>
</section>
<li class="icon">
☰
</li>
</ul>
</div>
</div>
<script src="js/responsive.js"></script>
Here is the CSS:
.container {
margin: auto;
width: 90%;
}
.navbar {
position: fixed;
z-index: 100;
overflow: hidden;
margin: auto;
width: 100%;
left:0;
top:0;
}
.navbar li.logo,
.navbar li.navbar_items {
list-style-type: none;
display: inline-block;
}
.navbar li a {
margin-top: 50px;
font-family: 'Cabin', sans-serif;
font-size: 1.3em;
color: white;
font-weight: 700px;
display: inline-block;
text-align: center;
padding: 10px 16px;
text-decoration: none;
}
.navbar li.navbar_items a:hover {
border-bottom-style: solid;
border-bottom-color: white;
/* padding-bottom: 5px; */
}
.navbar li.icon {
display: none;
}
.div_navbar_items {
float: right;
padding-right:1%;
}
/*Start of mobile nav*/
#media screen and (max-width:875px) {
.navbar li.navbar_items {
display: none;
}
.navbar li.icon {
float: right;
display: inline-block;
position: absolute;
right: 0;
top: 19px;
}
}
#media screen and (max-width:875px) {
.navbar.responsive {
position:fixed;
width: 100%;
height: 100vh;
background-color: rgba(236,201,205, 1);
transition: background-color .6s;
}
.navbar.responsive li.logo {
floatL: left;
display: block;
}
.navbar.responsive .div_navbar_items {
float: none;
padding-right:0;
}
.navbar.responsive li.navbar_items {
display: block;
padding: 50px;
font-size: 25px;
}
.navbar.responsive li.navbar_items a {
display: block;
text-align: center;
}
.navbar.responsive li.navbar_items a:hover{
color:#17171e;
border-bottom-color: transparent;
}
}
/*End of mobile nav*/
And here is the JS:
function navBarFunction() {
document.getElementsByClassName("navbar")[0].classList.toggle("responsive");
}
codepen: https://codepen.io/anon/pen/JyEoWY
I think this will get you in the right direction, then you can decide upon what you'd like to do from here. You are setting your navbar to be 100vh, which is 100% height of the screen, so you need to make sure your padding and margin on your nav elements aren't so much. Try removing any margin and padding from these two styles, then adapt it on your own from here. If you don't want to change this stuff, refer to the second part of my answer, and just make the nav scrollable.
.navbar li a {
margin-top: 0px;
}
#media screen and (max-width: 875px) {
.navbar.responsive li.navbar_items {
display: block;
padding: 0px;
font-size: 25px;
}
}
Also, if you look in .navbar styling (line 8 of your codepen) you have it set to overflow: hidden. You can update your .navbar.responsive class with overflow of scroll to get it to work.
#media screen and (max-width:875px) {
.navbar.responsive {
position:fixed;
width: 100%;
height: 100vh;
background-color: rgba(236,201,205, 1);
transition: background-color .6s;
overflow: scroll; // Set overflow to scroll
}
}
I guess this happenes because you make .navbar.responsive {
position:fixed;
And you just can't watch all content of block, because it's not allow to scroll. When i change this property to absolute, i looked all items of menu.
By the way, you write CSS property font-weight with px, font-weight: 700px, but it shouldn't be px, it's relative value: font-weight: 700

HTML Dropdown Returns Blank

For some reason, my HTML dropdown menu is returning completely blank values. However, you can see the values when you hover your mouse over them. My code is at my GitHub here: https://github.com/kekTEHfrahg/bengalidabbois/blob/master/index.html
EDIT: Sorry, got the wrong link. I fixed it now.
Also, for the specific code with my dropdown:
<div translate="no" class="compact marquee" id="div_language">
<select id="select_language" onchange="updateCountry()">
<option value="0">Afrikaans</option><option value="1">Bahasa Indonesia</option><option value="2">Bahasa Melayu</option><option value="3">Català</option><option value="4">Čeština</option><option value="5">Dansk</option><option value="6">Deutsch</option><option value="7">English</option><option value="8">Español</option><option value="9">Euskara</option><option value="10">Filipino</option><option value="11">Français</option><option value="12">Galego</option><option value="13">Hrvatski</option><option value="14">IsiZulu</option><option value="15">Íslenska</option><option value="16">Italiano</option><option value="17">Lietuvių</option><option value="18">Magyar</option><option value="19">Nederlands</option><option value="20">Norsk bokmål</option><option value="21">Polski</option><option value="22">Português</option><option value="23">Română</option><option value="24">Slovenščina</option><option value="25">Slovenčina</option><option value="26">Suomi</option><option value="27">Svenska</option><option value="28">Tiếng Việt</option><option value="29">Türkçe</option><option value="30">Ελληνικά</option><option value="31">български</option><option value="32">Pусский</option><option value="33">Српски</option><option value="34">Українська</option><option value="35">한국어</option><option value="36">中文</option><option value="37">日本語</option><option value="38">हिन्दी</option><option value="39">ภาษาไทย</option></select> <select id="select_dialect" style="visibility: visible;">
<option value="en-AU">Australia</option><option value="en-CA">Canada</option><option value="en-IN">India</option><option value="en-NZ">New Zealand</option><option value="en-ZA">South Africa</option><option value="en-GB">United Kingdom</option><option value="en-US">United States</option></select>
</div>
</div>
Here is the CSS code. Honestly, I don't find anything wrong with it. Is there something wrong with the CSS that makes the dropdown blank?
<style>
.speech {border: 1px solid #DDD; width: 300px; padding: 0; margin: 0}
.speech input {border: 0; width: 240px; display: inline-block; height: 30px;}
.speech img {float: right; width: 40px }
l {
border: ipx solid black
}
/* Style the tabs */
ul.tab {
list-style-type: none;
border-radius:10px;
margin: 0;
padding: 0;
overflow: hidden;
border: 1px solid #ccc;
background-color: #f2f2f2;
}
/* Float the list items side by side */
ul.tab li {float: left;}
/* Style the links inside the list items */
ul.tab li a {
background-color:#d9d9d9;
display: inline-block;
color: black;
text-align: center;
padding: 14px 16px;
text-decoration: none;
transition: 0.3s;
font-size: 17px;
}
/* Change background color of links on hover */
ul.tab li a:hover {
background-color:#999999 ;
}
/* Create an active/current tablink class */
ul.tab li a:focus, .active {
background-color: #ccc;
}
/* Style the tab content */
.tabcontent {
border-radius:10px;
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}
/* All content below pertains to the function of the tabs in an "accordian" style */
button.accordion {
border-radius:26px;
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
button.accordion.active, button.accordion:hover {
background-color: #ddd;
}
button.accordion:after {
content: '>>';
color: #777;
font-weight: bold;
float: right;
margin-left: 5px;
}
button.accordion.active:after {
content: "<<";
}
div.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
#info {
font-size: 20px;
}
#div_start {
float: right;
}
#headline {
text-decoration: none
}
#results {
font-size: 14px;
font-weight: bold;
border: 1px solid #ddd;
padding: 15px;
text-align: left;
min-height: 150px;
}
#start_button {
border: 0;
background-color:transparent;
padding: 0;
}
.interim {
color: gray;
}
.final {
color: black;
padding-right: 3px;
}
.button {
display: none;
}
.marquee {
margin: 20px auto;
}
#buttons {
margin: 10px 0;
position: relative;
top: -50px;
}
#copy {
margin-top: 20px;
}
#copy > div {
display: none;
margin: 0 70px;
}
body, h1,h2,h3,h4,h5,h6 {font-family: "Montserrat", sans-serif}
.w3-row-padding img {margin-bottom: 12px}
/* Set the width of the sidebar to 120px */
.w3-sidebar {width: 120px;background: #222;}
/* Add a left margin to the "page content" that matches the width of the sidebar (120px) */
#main {margin-left: 120px}
/* Remove margins from "page content" on small screens */
#media only screen and (max-width: 600px) {#main {margin-left: 0}}
</style>
It looks like the W3Schools style sheet sets the text color of every element to white (color: #fff!important;).
This can be easily remedied with changing the text color for select and option elements:
select, option {
color: black;
}
You can debug something like this by opening your browser's development tools, right-clicking the element and looking at the CSS used to render the element. In this particular case, your body tag uses the w3-green class, which has the following CSS by default:
.w3-green, .w3-hover-green:hover {
color: #fff!important;
background-color: #4CAF50!important;
}
In addition, the normalize style sheet (which has the highest specificity for the select elements) tells the browser to inherit the color from the parent (there's no other color declarations in each of select's parents until it reaches the body tag).
button, input, optgroup, select, textarea {
margin: 0;
font: inherit;
color: inherit;
}
You have a lot of CSS libraries and they are interfering with each other. Bootstrap.min.css is setting the color of your select to "inherit". Add this after bootstrap's style to fix that.
select {color:black;}
You can debug your code by using your browser's developer tools and see what style is being applied to your elements and from which library.

JQuery responsive menu won't work

I'm a novice web developer with no real jquery knowledge, so please bear with me. I'm trying to make a simple mobile responsive dropdown menu (ideally I'd like a slide down, but baby steps first). For the most part, I figured it out. However, I assigned my "Unordered List" an ID selector and it doesn't seem to function anymore. What am I overlooking? Thanks in advance!
This is my code: JSFiddle
$(document).ready(function(){
$('#toggle-button').click(function(){
$('#menu').toggleClass('show');
});
});
.show {
display: block;
}
nav {
background: black;
width: 100%;
}
.menu-bar {
width: 100%;
background: black;
height: 50px;
}
#toggle-button {
position: absolute;
top: 15px;
right: 60px;
height: 35px;
width: 35px;
background: red;
cursor: pointer;
display: block;
}
#menu {
list-style: none;
width: 100%;
display: none;
margin: 0px;
padding: 0px;
}
#menu li {
height: 50px;
background: #535252;
}
#menu li a {
display: block;
width: 100%;
height: 50px;
text-align: center;
line-height: 50px;
color: white;
text-decoration: none;
cursor: pointer;
}
#menu li:hover {
background: gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="menu-bar"></div>
<nav>
<ul id="menu">
<li>Profile</li>
<li>Profile</li>
<li>Profile</li>
</ul>
</nav>
<a id="toggle-button" href="#"></a>
Use:
#menu.show {
display: block;
}
after! you defined your defaults for #menu {
https://jsfiddle.net/nw2wf3uh/6/
or use the not-so-nice !important:
https://jsfiddle.net/nw2wf3uh/7/
.show {
display: block !important; /* if .show is placed before #menu styles in CSS */
}
You can also go the other way around, setting to your #menu a .hide by default:
<ul id="menu" class="hide">
CSS:
.hide {
display: none; /* but remove display:none; from #menu now! */
}
and toggle that .hide class:
$('#toggle-button').click(function(){
$('#menu').toggleClass('hide');
// or simply: $('#menu').toggle();
});
Here you'll not run into overriding styles cause of priority and you'll not have to use the !important fix (but you might have issues with JS-disabled users if that's of any concern (you should not care much but it always depends.)).

Categories