How to target another element to join with another positioned element? - javascript

I've been going through problems in positioning navbar even after the fact that its responsive. Problem comes when zooming in and zooming out (except for Mozilla), and I got no choices than asking experts for a solution because I am a noob in coding.
Chrome zoom-out: https://s31.postimg.org/kjnbou0yj/zoom_out_chrome.png
Mozilla zoom-out (also perfect in zoom-in): https://s31.postimg.org/ud3lz1i3v/zoom_out_moz.png
Basically, I want to join my navbar with another div element so that it do not move from its position and I don't know how to use :target etc, and do not even know if target will solve my problem.
My need: I just need my navbar to stick to one size. With current settings, it is working PERFECTLY with MOZILLA ONLY. I don't know why it show blank space in chrome and other browsers when zoom-out and when zoom-in. Working fine with Chrome 100% zoom and working fine with Opera 100% zoom. The problem comes when zooming in or zooming out. Again, it is working perfectly for mozilla in zooming etc, no such problems with mozilla. And my navbar is responsive too.
My guess: I think that attaching this navbar with hidden div class could solve this problem. BUT I am a complete noob in coding and I can just guess.
Here is the code of my navbar:
ul.pnav {
position: relative;
border-top-left-radius: 15px;
border-top-right-radius: 15px;
border: none;
list-style-type: none;
width: 900px;
height: 55px;
margin: auto;
top: 281px;
left: 0;
right: 0;
padding: 0;
overflow: hidden;
background-color: #767676;
z-index: 9999;
}
#-moz-document url-prefix() {
ul.pnav {
top: 286px
}
}
ul.pnav li {float: left;}
ul.pnav li a {
display: inline-block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
transition: 3s;
font-size: 17px;
font-family: Arial;
font-weight: bold;
}
ul.pnav li a:hover {background-color: #111;}
ul.pnav li.icon {display: none;}
#media screen and (max-width:680px) {
ul.pnav li:not(:first-child) {display: none;}
ul.pnav li.icon {
float: right;
display: inline-block;
}
}
#media screen and (max-width:680px) {
ul.pnav.responsive {position: relative;}
ul.pnav.responsive li.icon {
position: absolute;
right: 0;
top: 0;
}
ul.pnav.responsive li {
float: none;
display: inline;
}
ul.pnav.responsive li a {
display: block;
text-align: left;
}
}
I have this in html as a code:
<ul class="pnav">
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li class="icon">
☰
</li>
</ul>
This is div class to which I want to attach navbar.
<div class="fornavbar"></div>
I don't know how to proceed further, please help.

Look at this fiddle: https://jsfiddle.net/8qepe4gw/2/
In order for them to align together you just simply put them both inside of a common div like this (.container),
<div class="container">
<ul class="pnav">
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li class="icon">☰</li>
</ul>
<div class="fornavbar"></div>
</div>
And then you assign a width to the .container, and then you can give both the .pnav and .fornavbar a width of 100% so they stretch all the way out inside of the container, as in they have the same width.
Now the reason why it only worked in firefox is probably because of this part of the code:
#-moz-document url-prefix() {
ul.pnav {
top: 286px
}
}
Because #-moz-document only targets firefox.
It's still gonna work in all browsers now though with the new code I added in the fiddle so you shouldn't have to worry about it, perhaps even delete that part of the CSS code(?).

Related

Dropdown menu not aligning

I'm having a problem where my list for my dropdown menu appears in another location then expected to be at.
This is part of my code. I've tried multiple references, like YouTube, w3school, and etc.
(HTML / JS)
.dropdownButton {
color: #fe4b4b;
text-decoration: none;
font-family: 'Titillium Web', sans-serif;
font-size: 165%;
background-color: transparent;
background-repeat: no-repeat;
border: none;
cursor: pointer;
overflow: hidden;
outline: none;
}
.dropdown {
align-items: center;
}
.list {
position: absolute;
align-items: center;
text-align: center;
transform: scaleY(0);
transform-origin: top;
transition: 0.3s;
height: auto;
width: 150px;
border-radius: 5px;
background-color: #3a4172;
cursor: pointer;
overflow: hidden;
box-shadow: 2px 0px 10px 5px rgba(0, 0, 0, 0.7);
list-style: none;
}
.newlist {
transform: scaleY(1);
}
.links {
color: #ffffff;
text-decoration: none;
font-family: 'Titillium Web', sans-serif;
font-size: 130%;
background-repeat: no-repeat;
background-color: transparent;
border: none;
border-radius: 5px;
width: 100%;
}
.links:hover {
color: #fefb4b;
border-left: 5px solid #fefb4b;
cursor: pointer;
transform: scale(1.025);
}
<header>
<ul>
<li id="regular">EARN</li>
<li id="regular">PROMOCODES</li>
<li id="regular">WITHDRAW</li>
<li class="dropdown">
<button class="dropdownButton" href="#">MORE ▼</button>
<ul class="list">
<button class="links">REFFERALS</button>
<button class="links">DAILY</button>
</ul>
</li>
<li id="login">SIGN UP</li>
</ul>
<script>
//Dropdown
let click = document.querySelector('.dropdownButton');
let list = document.querySelector('.list');
click.addEventListener("click", () => {
list.classList.toggle('newlist');
});
//Dropdown End
</script>
</header>
I don't know how to fix it cause I'm a beginner, any help on fixing it / guidance would be nice! Thanks.
We're going to need more CSS and possibly HTML to see exactly why your code is behaving unexpectedly.
Definitely mimicking the first comment on here though: IDs should be unique to each element. If you want those li elements to have the same styling, use a class:
<li class="regular">
This will apply the same styling to different elements.
However, when an element appears in the top left like that, in my experience, I am using the CSS 'display', 'float', or 'position' properties incorrectly. If you haven't already, look into how the float and display properties function (as well as relative vs absolute positioning).
Check out this codepen.io, where I have it working by adding:
li {
float: left;
}
This allows your list items to exist on the same line properly. My guess is that you are using
li {
display: inline; /* incorrect usage */
}
to get them on the same horizontal axis. This is fine for regular text elements, but will cause "unexpected" behavior with positioning of child elements. For a more detailed explanation, please see this StackOverflow post:
What is the purpose of float:left on an unordered list when creating a horizontal navigation bar?.
Tip for next time: if your local looks very different than what you get if you paste into codepen.io, people will be less inclined to help you.
If this properly answered your question please upvote and mark best answer :)

JS dropdown menu best practice

I want to implement the following tiny drop down menu into my project.
Is there anything inherently wrong with my code? I attempted the :hover pseudo via CSS but was unsuccessful. Is there a better way to JS this thing?
document.querySelector('.dropbtn').addEventListener('mouseenter', function(){
document.querySelector('.dropdown-content').style.visibility = 'visible'
})
document.querySelector('.dropbtn').addEventListener('mouseleave', function(){
document.querySelector('.dropdown-content').style.visibility = 'hidden'
})
.dropdown {
display: flex;
align-items: flex-start;
}
.dropbtn {
background-color: darkslategray;
color: white;
padding: 6px 10px 6px;
font-size: 18px;
border: none;
cursor: pointer;
}
.dropdown-content {
background-color: darkslategray;
display: inline-grid;
visibility: hidden;
padding: 6px 10px 6px;
}
img {
margin: 3px;
height: 40px;
width: 120px;
border: 1px solid gray;
}
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
<img src="http://fullhdpictures.com/wp-content/uploads/2016/03/Blur-Backgrounds.jpg" alt="">
<img src="http://akveo.com/blur-admin/assets/img/blur-bg-blurred.jpg" alt="">
<img src="http://www.publicdomainpictures.net/pictures/50000/velka/blurred-background-green.jpg" alt="">
</div>
</div>
Codepen: https://codepen.io/HelleFl/pen/KyWYYX
Although there are several posts describing how to create a dropdown menu using just HTML and CSS, I'll try to answer your question.
tl;dr: Use CSS over JS for better performance
CSS or JS? Which one is better?
Basically whenever possible, use CSS over JS. There is a great SO answer about this here.
Going further, CSS animations should be preferred over JS animations unless the animation should have some advanced effects. There is a good google developers blog post on this as well.
How to create a dropdown menu
You can find the answer here. Basically you need to set the :hover onto the parent element, that holds both the link and submenu.
li img {
width: 120px;
height: auto;
}
ul > li {
display: inline;
position: relative;
min-width: 150px;
}
/* hide submenus by setting the max-height to 0 */
ul > li > ul {
max-height: 0;
overflow: hidden;
transition: max-height .75s ease;
}
/* set max-height to an approximate height it could have */
ul > li:hover > ul {
max-height: 300px;
}
ul.submenu {
background: #eee;
position: absolute;
left: 0;
top: 1em;
}
ul.submenu > li {
display: block;
}
<nav>
<ul>
<li>Hyperlink 1</li>
<li>
Hyperlink 2
<ul class="submenu">
<li><img src="http://fullhdpictures.com/wp-content/uploads/2016/03/Blur-Backgrounds.jpg" alt=""></li>
<li><img src="http://akveo.com/blur-admin/assets/img/blur-bg-blurred.jpg" alt=""></li>
<li><img src="http://www.publicdomainpictures.net/pictures/50000/velka/blurred-background-green.jpg" alt=""></li>
</ul>
</li>
</ul>
</nav>
I guess you was facing the same issue that I was facing when I checked your codepen, since the .dropbtn are in the same level as .dropdown-content, the selector .dropbtn:hover .dropdown-content wont work since its searching for a child inside .dropbtn, so you have to use the sibling selector:
.dropbtn:hover ~ .dropdown-content{
visibility: visible
}
(CSS animation its better than Javascript)
Also, a good practice in Javascript is to save the DOM element into an variable if you will use it multiple times, so you dont have to search for the DOM element again:
var dropBtnDOM = document.querySelector('.dropbtn');
var dropdownContentDom = document.querySelector('.dropdown-content');
dropBtnDOM.addEventListener('mouseenter', function(){
dropdownContentDom.style.visibility = 'visible'
})
dropBtnDOM.addEventListener('mouseleave', function(){
dropdownContentDom.style.visibility = 'hidden'
})
.dropdown:hover .dropbtn ~ .dropdown-content{
visibility: visible
}

jquery slidetoggle() not hiding :before element

All of my elements hide and show correctly using slidetoggle(), EXCEPT for my li:before. I've tried forcing the overflow, visibility, display, etc on the :before and the li, and nothing is helping, it still shows the bullets set using the :before class. What needs to happen to hide these bullets when slidetoggle() is activated/deactivated?
jQuery(document).ready(function($) {
$("#read-more").click(function(){
$(".careers-position").slideToggle(800);
return false;
});
});
ul {
line-height: 2.4em !important;
margin-left: 20px;
padding: 0 0 23px 1em;
}
li {
list-style: none !important;
color: #656565;
}
li:before {
content: "";
background: #9e9e9e;
width: 6px;
height: 6px;
display: block;
position: absolute;
left: 18px;
margin-top: 16px;
border-radius: 20px;
overflow: hidden;
backface-visibility: hidden;
}
.careers-position {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="careers-position">
<h3>Pilot</h3>
Position information will go here.
We are an equal opportunity employer and all qualified applicants will receive consideration for employment.
<strong>Requirements:</strong>
<ul>
<li>Multi Commercial (ATP preferred)</li>
<li>First Class Medical</li>
<li>Passport</li>
<li>90 day currency</li>
<li>Clean FAA record</li>
</ul>
</div>
<div class="careers-read-more">
<a class="quick-btn" id="read-more" href="#">Read More</a>
</div>
Add position relative:
.careers-position {
display: none;
position: relative;
}
Demo
Here look at this fiddle https://jsfiddle.net/wfccp58p/4/
ul { line-height: 2.4em; margin-left: 20px;padding: 0 0 23px 1em;list-style-type: none;}
I removed the li:before and added the list-style-type to the ui. Not sure if you still wanted some of the LI:Before pseudo stuff, but this fixes your issue.

Responsive nav not appearing as intended

I am trying to create a responsive nav bar, but I am coming across issues making it appear in the way intended.
Here is an image of how it looks when window is maximized:
Here is an image when the window is resized:
Here is an image of what I want the page to look and function like:
Issues:
As the images show, the header currently shows the links "stretches, mobility" etc, when I want it to display "Join / Log In" etc (image 3).
When menuis clicked, I want the nav to dynamically display the other links.
Here is what I have tried so far: https://jsfiddle.net/hudnybux/
Ok, I think I got it to look almost exactly like your screenshots. One of the main things I had to do was move your nav-trigger up within html.
<div id="header-main">
<div id="nav-trigger"><span>Menu</span></div>
<nav id="main-navigation" role="navigation">
<ul>
<li>Stretches</li>
<li>Mobility</li>
<li>Posture</li>
</ul>
</nav>
<!--<nav id="nav-mobile"></nav>-->
</div>
Technically you no longer need nav-mobile nav. I also fixed your caret triangle next to "menu". It needed a height and width of 0.
width: 0;
height: 0;
Edit:
I have revisited my solution. Just as a suggestion, I am recommending css transitions instead of jQuery slideDown and slideUp. You were already applying a class and that is all we need to create dynamic animations. jQuery's methods apply the styles inline and frankly leave you with less flexibility.
https://jsfiddle.net/qnco3x7e/8/
You will need to add another media query
#media all and (max-width: 460px) {
nav#main-navigation li {
display:block;
border-bottom: 1px solid #fafafa;
}
}
You can use flexbox css properties. It's very powerfull. http://www.alsacreations.com/tuto/lire/1493-css3-flexbox-layout-module.html
Writing others' code for them is not in the spirit of Stack Overflow, but, as I prefer teaching by showing and not telling, I went ahead and did the task for you. Observe how I changed your implementation and learn as much as you can!
The Strategy
Use the same HTML markup for the main menu (Stretches, Mobility, Posture) on both large and small screen widths, instead of using JavaScript to duplicate it in two places.
Use the same CSS for both menus as a starting point; in the media query for small screen sizes, change the main menu to be horizontal
Show everything by default; use display: none only on screen sizes you don't want to show something on.
JSFiddle
$(document).ready(function() {
$("#main-nav-mobile-trigger span").click(function() {
$(this).toggleClass("open");
if ($(this).hasClass("open")) {
$("#main-nav").addClass("open").slideDown(250);
} else {
$("#main-nav").removeClass("open").slideUp(250);
}
});
});
.pageOverlay {
width: 900px;
margin: 0 auto;
}
/******************/
nav {
background-color: #fefefe;
/*NAV COLOUR*/
padding: 10px 0;
border-bottom: 1px solid #e3e3e3;
text-align: center;
}
nav ul li a {
color: #a4a4a5;
text-decoration: none;
}
nav ul li a:hover {
color: black;
}
nav ul {
display: inline-block;
list-style-type: none;
margin: 0;
padding: 0;
text-align: center;
}
nav li {
display: inline-block;
padding: 0 2px;
}
nav li:last-child {
border-right: none;
}
nav a {
display: block;
color: white;
padding: 10px 20px;
}
/****************************************************************/
/* Menu CSS which pops up when window is resized */
#main-nav-mobile-trigger {
text-align: center;
}
#main-nav-mobile-trigger span {
display: inline-block;
padding: 10px 30px;
cursor: pointer;
text-transform: uppercase;
}
#main-nav-mobile-trigger span:after {
display: inline-block;
margin-left: 10px;
width: 20px;
height: 10px;
content: "";
border-left: solid 10px transparent;
border-top: solid 10px #e3e3e3;
border-right: solid 10px transparent;
}
#main-nav-mobile-trigger span:hover {
background-color: #e3e3e3;
}
#main-nav-mobile-trigger span.open:after {
border-left: solid 10px transparent;
border-top: none;
border-bottom: solid 10px #fff;
border-right: solid 10px transparent;
}
#media all and (min-width: 901px) {
#top-nav {
text-align: right;
}
#main-nav {
text-align: left;
}
#main-nav-mobile-trigger {
display: none;
}
}
#media all and (max-width: 900px) {
#main-nav:not(.open) {
display: none;
}
#main-nav ul {
display: block;
}
#main-nav li {
display: block;
border-bottom: solid 1px #e3e3e3;
}
#main-nav li:last-child {
border-bottom: none;
}
#main-nav a {
padding: 10px 30px;
}
#main-nav a:hover {
background-color: #e3e3e3;
color: #fff;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pageOverlay">
<nav id="top-nav" role="navigation">
<ul>
<li>Join / Log In</li>
<li>Help</li>
<li>Shop</li>
</ul>
</nav>
<div id="main-nav-mobile-trigger"><span>Menu</span></div>
<nav id="main-nav" role="navigation">
<ul>
<li>Stretches</li>
<li>Mobility</li>
<li>Posture</li>
</ul>
</nav>
</div>
<!-- pageOverlay closed-->
The HTML
I removed your container <div>s (#header and #header-main), as they serve no purpose as far as layout is concerned.
There are now only three parts to the header area. In order they are:
#top-nav - Join/Login, Help, Shop
#main-nav-mobile-trigger - MENU button
#main-nav - Stretches, Mobility, Posture
The JavaScript
When the MENU button (#main-nav-mobile-trigger span) is clicked:
Toggle its .open class.
If it has the .open class,
Add #main-nav's .open class.
Otherwise,
Remove #main-nav's .open class.
The CSS
You had duplicates of the styling rules for each horizontal menu (formerly #nav-main and #main-navigation, which are very easy to confuse). These are now combined into one set of rules under the more general selector, nav. Additionally, their text-align is set to center by default (the desired alignment on small screen widths).
For big screen widths (#media all and (min-width: 901px)):
Align #top-nav to the right and #main-nav to the left.
Hide the MENU button.
For small screen widths (#media all and (max-width: 900px)):
If #main-nav doesn't have the .open class, hide it.
Display the menu items in #main-nav horizontally.
I hope this helps you. Best of luck with your future adventures in front-end development!

center align menu with equal spacing

I have a menu like this
Home About Privacy Shopping Contact Us
I want to show this menu in the center of its container (whatever the width of the container is). I can apply 20% width to these list-item but then some list-item has more spacing in between and others have little due to different sizes of texts
<div id="container">
<ul>
<li><a>Home</a></li>
<li><a>About</a></li>
<li><a>Privacy</a></li>
<li><a>Shopping</a></li>
<li><a>Contact us</a></li>
</ul>
</div>
Try using Flex Box layout (Demo):
#container ul {
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
-ms-box-orient: horizontal;
box-orient: horizontal
}
#container li {
-webkit-box-flex: 1;
-moz-box-flex: 1;
-ms-box-flex: 1;
box-flex: 1;
border: solid 1px #000;
text-align: center
}
This method allows you to use your 20% width and center the items in your container, all while keeping the same width of each item.
ul {
list-style-type: none;
width: 700px;
margin: 0 auto;
}
#container {
width: 800px;
background: #CC9;
}
li { display: block;
float: left;
width: 20%;
margin-left: -5px;
background: #399;
text-align: center;
border: solid black 1px;
color: white;
}
which you can view here... http://jsfiddle.net/r6Wwf/15/
I added a negative margin-left to compensate for the border I added so you get a better visual of how it works. I also set the width of the ul to 700px. This could be any width.
To set the entire menu in the center of a container add this to your css:
ul { margin: 0 auto; }
And then add a width to your container. This is all in the fiddle. You can set the width of the container to whatever you want. I have it at 800px.
If you're okay adding a containing element (nav is probably the most suitable), here's a good solution for you:
HTML:
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Privacy</li>
<li>Shopping</li>
<li>Contact us</li>
</ul>
</nav>
CSS:
nav { overflow: hidden; }
nav ul {
float: left;
position: relative;
left: 50%;
padding: 0;
list-style: none; }
nav ul li {
float: left;
position: relative;
right: 50%;
margin: 0 10px; }
nav ul li a {
padding: 5px;
display: block; }
Preview: http://jsfiddle.net/Wexcode/bKH79/
If you want each li element to be 20% of the width of the container, just set the container to have width: 100% and set each li element to have width: 100% (you would also need to remove the margin from the li and add text-align: center).
See: http://jsfiddle.net/Wexcode/bKH79/2/
The best way to horizontally center elements in CSS is to give it a specific width, and then give it margin: auto;. Here is an example I made real quick. You can see the ul (blue border) has a width of 300px and it sits centered inside the 500px container (red border): http://jsfiddle.net/r6Wwf/4/. You can space the list elements however you would like.
What is the container width exactly..?
ok Let me assume its 960px now give width to your ul element so that the list item will not go in second line.Suppose it has taken 600px now in this case your CSS for making menu items in CENTER will be:
.container{width:960px;}
.container ul{width:600px;margin:auto}
Hope it'll solve your problem.
Pretty simple.
div#container {
width: 300px;
margin: auto 0;
}
div#container li {
display: inline-block;
padding: 15px;
}
You would definitely need to write some JavaScript to make this happen. This is how I would do it... http://jsfiddle.net/rb39A/1/
By using a little bit of jQuery you can get the dynamically sized containers you're looking for.

Categories

Resources