How to "push" the whole page content to left? - html

I try to achieve the side navbar just looks like this website:
https://shop.hitsujigusa.com/
And I'm using the W3Schools method now (the push one):
https://www.w3schools.com/howto/howto_js_sidenav.asp
But the W3Schools method is much more looks like "squish" the page not "push".
And I also want to open and close the menu using the same button, not separate.
how can I do this? much appreciate!
this is my html now:
<body>
<div id="mySidenav" class="sidenav">
<a href="javascript:void(0)" class="closebtn" onclick="closeNav()">
X
</a>
home
about
products
contact
links
</div>
<div id="main">
(...content here...)
</div>
and the js
function openNav() {
document.getElementById("mySidenav").style.width = "250px";
document.getElementById("main").style.marginRight = "250px";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
document.getElementById("main").style.marginRight= "0";
}

You will need the w3schools example and the one below, here is why. On mobile you will not have the space to squish the content and make it look good but on desktop you will and you don't want to move your content out of its container. So on mobile set the width and transform translate dynamically through JavaScript and when you get to desktop squish your content using width and margin as they do in the w3schools example.
const menuButton = document.getElementById("toggle-menu");
const mainNav = document.getElementById("main-nav");
const mainList = document.getElementById("main-list");
const mainContent = document.getElementById("main-content");
const toggleMenu = () => {
const listWidth = mainList.offsetWidth;
if (mainNav.getAttribute("aria-hidden") === "true") {
mainNav.style.width = listWidth + "px";
mainNav.setAttribute("aria-hidden", "false")
mainContent.style.transform = "translate(-" + listWidth + "px)"
} else {
mainNav.style.width = "0px";
mainNav.setAttribute("aria-hidden", "true");
mainContent.style.transform = "translateX(0)"
}
}
menuButton.addEventListener("click", toggleMenu);
.container {
position: relative;
/* for the example */
border: 3px solid red;
width: 375px;
height: 667px;
margin-left: 87px;
}
.navigation {
width: 0;
overflow: hidden;
position: absolute;
top: 0;
right: 0;
transition: width .3s ease-in-out;
}
#main-list {
list-style: none;
margin: 0;
padding: 0 1rem;
width: min-content;
}
#main-content {
transition: transform .3s ease-in-out;
/* for the example */
background-color: blue;
height: 100%;
}
<header><button id="toggle-menu">toggle menu</button></header>
<div class="container">
<div id="main-content">
(...content here...)</main>
</div>
<nav id="main-nav" class="navigation" aria-hidden="true">
<ul id="main-list">
<li><a href="javascript:void(0)" class="closebtn" onclick="closeNav()">
X
</a></li>
<li>home</li>
<li>about</li>
<li>products</li>
<li>contact</li>
<li>links</li>
</ul>
</nav>
</div>

Related

Why isn't my javascript changing my css to make my button work?

I'm making a navigation bar and my goal is that when you're a mobile device and you click the menu button or "nav-toggle", the whole navigation bar which is hidden at the max-width of 35em should be showing up on button click.
const ulNav = document.querySelector(".ul-navbar");
const navButt = document.querySelector(".nav-toggle");
//on click visibility is checked, if its "false", the data-visible attribute in css would be set to true and if its "true" it would be set to false.
navButt.addEventListener("click", () => {
const vis = ulNav.getAttribute('data-visible');
console.log(vis)
if (vis === "false") {
ulNav.setAttribute("data-visible", true);
} else if (vis === "true") {
ulNav.setAttribute("data-visible", false);
}
});
/* p-head */
.primary-header {
align-items: center;
justify-content: space-between;
}
/* for mobile devices */
#media (max-width: 35em) {
.ul-navbar {
position: fixed;
z-index: 1000;
top: 0;
bottom: 0;
right: 0;
left: 30%;
flex-direction: column;
padding: min(30vh, 10rem) 2rem;
transform: translateX(100%);
}
/* what the javscript should be changing */
.ul-navbar [data-visible="true"] {
visibility: visible;
transform: translateX(0%);
}
.nav-toggle {
display: block;
position: absolute;
z-index: 9999;
background: url(amburger.png);
background-repeat: no-repeat;
width: 1rem;
height: 1rem;
background: red;
top: 2rem;
right: 2rem;
}
}
<body>
<header class ="primary-header flex" >
<div class="logo">
<a href="index.html">
<img class = "img" src="./imges/beatlejuce.png" alt="logo">
</a>
</div>
<button class="nav-toggle" aria-controls="ul-nav" aria-expanded="false">Menu</button>
<nav>
<ul id="ul-nav" data-visible="false" class ="ul-navbar flex">
<li>home</li>
<li>code</li>
<li>photography</li>
<li>random</li>
<li>login</li>
</ul>
</nav>
</header>
What should be happening is on button click the javascript changes the css inside of the max-width media query making the data-visible="true" to "false" and back if button is to be clicked again. For some reason, nothing is changing, maybe I had some type of error in my use of data-visible, but if its not that, I dont really know how to fix this.
Because you are trying to find your element like a class. Change your const ulNav to this:
const ulNav = document.querySelector("#ul-navbar");
There is an incorrect selector here:
.ul-navbar [data-visible=true] {
visibility: visible;
transform: translateX(0%);
}
Should be:
.ul-navbar[data-visible=true] {
visibility: visible;
transform: translateX(0%);
}

Display a Search bar on header on scroll HTML/CSS

I have a search bar which would like to display onto the header on scroll, a great example is like the one on this site: https://www.indiamart.com/
Approach 1 - A simple way to do this would be to detect a scroll & add and remove a class that contains display: none;
You can have an event listener -
window.addEventListener('scroll', function() {
if( window.scrollY !== 0) {
document.getElementById('searchBar').classList.add('scrolled');
} else {
document.getElementById('searchBar').classList.remove('scrolled');
}
});
With the CSS -
.noScroll
{
background: yellow;
position:fixed;
height: 50px; /*Whatever you want*/
width: 100%; /*Whatever you want*/
top:0;
left:0;
display:none;
}
/*Use this class when you want your content to be shown after some scroll*/
.scrolled
{
display: block !important;
}
.parent {
/* something to ensure that the parent container is scrollable */
height: 200vh;
}
And the html would be -
<div class="parent">
<div class ='noScroll' id='searchBar'>Content you want to show on scroll</div>
</div>
Here's a JSFiddle of the same - https://jsfiddle.net/kecnrh3g/
Approach 2 -
Another simple approach would be
<script>
let prevScrollpos = window.pageYOffset;
window.onscroll = function() {
let currentScrollPos = window.pageYOffset;
if (prevScrollpos > currentScrollPos) {
document.getElementById('searchBar').style.top = '-50px';
} else {
document.getElementById('searchBar').style.top = '0';
}
prevScrollpos = currentScrollPos;
}
</script>
with the html -
<div class="parent">
<div id ='searchBar'>Content you want to show on scroll</div>
</div>
and css
#searchBar {
background: yellow;
position: fixed;
top: 0;
left: 0;
height: 50px;
width: 100%;
display: block;
transition: top 0.3s;
}
.parent {
height: 200vh;
}
Here's a JSFiddle of the same - https://jsfiddle.net/0tkedcns/1/
From the same example, the idea is only to show/hide once user scroll the page using inline css display property, you can do the same or at least provide a code sample so we can help you!
HTML
<div class="search-bar">
<div class="sticky-search">
Sticky Search: <input type="text" value="search" />
</div>
</div>
CSS
.sticky-search {
display:none;
position:fixed;
top:0px;
left:0px;
right:0px;
background:blue;
padding:10px;
}
JS
var searchHeight = $(".search-bar").outerHeight();
var offset = $(".search-bar").offset().top;
var totalHeight = searchHeight + offset;
console.log(totalHeight);
$(window).scroll(function(){
if($(document).scrollTop() >= totalHeight) {
$('.sticky-search').show();
} else {
$('.sticky-search').hide();
}
});

How to change data visible range to % percent

I am using this for my header that changes in a one page scroll up and down page. I noticed that it's not responsive so i am asking you if you maybe know a way to make that responsive. Like changing the 0-690 into a percentage so that it will work on mobile and also on a tv screen.
HTML
<div class="header header-1" data-visible-range="0-690">Portfolio</div>
<div class="header header-2" data-visible-range="691-2100">Services</div>
<div class="header header-3" data-visible-range="2101-">Contact</div>
CSS
.header-1 {
background-color:dimgray;
display: block;
}
.header-2 {
background-color:dimgray;
}
.header-3 {
background-color:dimgray;
}
.header {
position: fixed;
top: 0;
left: 0;
height:8vmax;
width: 100%;
display: none;
visibility:hidden;
transition: visibility .4s, opacity .4s ease-in-out;opacity:0;
font-size:4vmax;padding:1.58vmax;color:white;
}
What if, instead of basing it off pixels, you just checked to see if an element hit the top of the page, and then changed the header?
We'll call these elements "triggers." See my code below for an example of how they work.
let updateHeader = () => {
let scrollTop = $(window).scrollTop(),
triggerTitle = "Hi";
$('.trigger').each((i, el) => {
let topPos = $(el).offset().top,
distance = topPos - scrollTop;
if (distance < 0)
triggerTitle = $(el).data('title');
});
$('header h2').text(triggerTitle);
}
$(window).scroll(updateHeader);
$(window).on('touchmove', updateHeader);
body {
margin: 0;
}
#container {
height: 1000px;
}
header {
width: 100%;
position: fixed;
top: 0;
background-color: red;
}
p {
margin: 200px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<header><h2>Hi</h2></header>
<p class="trigger" data-title="section1">
trigger1
</p>
<p class="trigger" data-title="section2">
trigger2
</p>
<p class="trigger" data-title="section3">
trigger3
</p>
</div>
As you scroll down the page, each trigger hits the top of the page, and the text in the header will change to the the value of the latest trigger's data-title. You could position these triggers appropriately above each of your website's sections, so that, no matter what size the screen, the header should update at the right time. Here's a codepen.
EDIT
Try this JS instead for maximum compatibility (no es6 involved).
function updateHeader() {
var scrollTop = $(window).scrollTop(),
triggerTitle = "Hi";
$('.trigger').each(function(i, el) {
var topPos = $(el).offset().top,
distance = topPos - scrollTop;
if (distance < 0)
triggerTitle = $(el).data('title');
});
$('header h2').text(triggerTitle);
}
$(window).scroll(updateHeader);
$(window).on('touchmove', updateHeader);

Want p to stay in the same position

When I click the buttons, there is some text added to the ul which is at the top left.
my p is on the right of the page and it moves down as more text(row)s are added. I want it to stay there. What code should i add?
<ul id="elementlist">
</ul>
<button onclick="addWater()"> Add Water </button>
<button onclick="addFire()"> Add Fire </button>
<div style="float:right;">
<p>aaaa</p>
</div>
<script type="text/javascript">
function addWater() {
var node = document.createElement("LI");
var textnode = document.createTextNode("Water");
node.appendChild(textnode);
document.getElementById("elementlist").appendChild(node);
}
function addFire() {
var node = document.createElement("LI");
var textnode = document.createTextNode("Fire");
node.appendChild(textnode);
document.getElementById("elementlist").appendChild(node);
}
</script>
Wrap the <p> tag inside a custom div and apply position: fixed into that div and adjust top and right to make it work.
.custom-pos {
position: fixed;
right: 2%;
top: 0;
}
<ul id="elementlist">
</ul>
<button onclick="addWater()"> Add Water </button>
<button onclick="addFire()"> Add Fire </button>
<div class="custom-pos">
<p>aaaa</p>
</div>
You could use position fixed (or absolute) as suggested,
or you can achieve the same using flexbox, if you can avoid supporting old browsers:
function addWater() {
var node = document.createElement("LI");
var textnode = document.createTextNode("Water");
node.appendChild(textnode);
document.getElementById("elementlist").appendChild(node);
}
function addFire() {
var node = document.createElement("LI");
var textnode = document.createTextNode("Fire");
node.appendChild(textnode);
document.getElementById("elementlist").appendChild(node);
}
html,
body {
margin: 0;
overflow: hidden;
height: 100%;
}
.container {
overflow: hidden;
height: 100%;
display: flex;
}
.content {
padding: 5px;
flex: 1;
overflow: auto;
}
.sidebar {
padding: 5px;
flex: 0;
}
<div class="container">
<main class="content">
<ul id="elementlist">
</ul>
<button onclick="addWater()">Add Water</button>
<button onclick="addFire()">Add Fire</button>
</main>
<div class="sidebar">
<p>aaaa</p>
</div>
</div>

Hover header+Sub-header that adapts when scrolling

I'm new and learning to code a website!
I'm trying to do this hover header that when the user scroll down, it will remain on the screen and when the user reaches Sub-Header 1, it will hover it too and changes if the user reaches Sub-Header 2(Sub-Header 1 will then disappear)
This is what I'm working on http://goo.gl/KqAM2R
Thanks in advance!
http://i.imgur.com/flT3oJ1.jpg
You need to use JavaScript to achieve this effect. SSCCE:
NewFile.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="NewFile.js"></script>
<link rel="stylesheet" type="text/css" href="NewFile.css"></head>
<body>
<header class="fixed-top">Europe</header>
<div class="much-text">doge</div>
<header class="whatever1 doge">Heatwave</header>
<div class="much-text">doge</div>
<header class="whatever2 doge">2k15</header>
<div class="much-text">doge</div>
</body>
</html>
NewFile.js:
function isElementInViewport (el, topOrBottom) {
//special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
if(topOrBottom == "top"){
return rect.top >= 0;
}else{
return rect.bottom <= $(window).height();
}
}
function onVisibilityChange () {
var headers = document.getElementsByClassName("doge");
var headerAbove = null;
for(i = 0; i<headers.length; i++){
$( headers[i]).css("position","");
$( headers[i]).css("top","");
if(!isElementInViewport(headers[i], "top")){
headerAbove = headers[i];
}
}
if(headerAbove != null){
$( headerAbove).css("position","fixed");
$( headerAbove).css("top","30px");
}
}
$(window).on('DOMContentLoaded load resize scroll', onVisibilityChange);
And NewFile.css
#CHARSET "UTF-8";
.fixed-top{
width:100%;
position:fixed;
top:0px;
background-color: red;
}
.whatever1{
width:100%;
background-color: green;
}
.whatever2{
width:100%;
background-color: blue;
}
.much-text{
height: 2000px;
}
.doge {
}
Thanks to authors of answers in How to tell if a DOM element is visible in the current viewport? for an inspiration. Also, I am aware that this code doesn't meet all good practices writing in js & css but OP clearly can find the idea from this one. Notice that you may need to sort headers (from the top header to the bottom header) in your own way before iterating on them in function onVisibilityChange
Try this...
HTML
<div id="page" class="page">
<div class="container">
<div class="contentheadercontainer">
<div class="fsh"><div class="firstheader">Sub header 1</div></div>
<div class="fsh"><div class="secondheader" id='secondheader'><p style='margin-left: 15px;'>Sub header 2</p></div></div>
</div>
</div>
</div>
</div>
CSS
body{
padding: 0px; margin: 0px;
}
.container{
height: 1000px;
}
.fsh{
position: absolute; width: 100%;
}
.firstheader{
height: 30px;width: 100%; position:fixed; background: #B14345; padding: 15px; color: #fff;
}
.secondheader{
border-top: 1px solid #bbb; padding: 5px 0px 5px 0px; margin-top: 300px; width: 100%; background: #B14345;color: #fff;
}
Javascript
document.addEventListener("scroll", function(){
scrollDetect();
});
function scrollDetect(){
var html = document.documentElement;
var top = (window.pageYOffset || html.scrollTop) - (html.clientTop || 0);
if(top > 235){
document.getElementById('secondheader').style.position = 'fixed';
document.getElementById('secondheader').style.marginTop = '60px';
document.getElementById('secondheader').style.width='100%';
}else{
document.getElementById('secondheader').style.position = 'inherit';
document.getElementById('secondheader').style.marginTop = '300px';
}
}
Check out this JSFiddle