Fixed Content Scrolling Layout - html

The site below uses a fixed background-image in each section, but how do I add fixed content (text, images) to each sections and keep the same scrolling effect?
http://tympanus.net/Blueprints/ScrollingLayout/
Have a look at my example to get a better idea of what I want:
http://jsfiddle.net/w919y0gb/
My try:
#wrapper {
position: relative;
height: 500px;
width: 500px;
overflow: scroll;
}
.section {
position: relative;
height: 100%;
width: 100%;
}
.content {
position: fixed;
}
#s1 {
background-color: #f00;
}
#s2 {
background-color: #0f0;
}
#s3 {
background-color: #00f;
}
#s1 .content {
}
#s2 .content {
margin-top: -400px;
}
#s3 .content {
margin-top: -800px;
}
<div id="wrapper">
<div class="section" id="s1">
<div class="content">hello1</div>
</div>
<div class="section" id="s2">
<div class="content">hello2</div>
</div>
<div class="section" id="s3">
<div class="content">hello3</div>
</div>
</div>
What I want:
The first section (red) should only display "hello1"
The second (green) only "hello2"
The third (blue) only "hello3"

something like this maybe? little hacky, but does the trick if you have set section heights:
$(document).ready(function(){
$('.div3').hide();
$('.div2').hide();
$('.div1').show();
$('#wrapper').scroll(function(){
console.log($('#wrapper').scrollTop());
if($('#wrapper').scrollTop() > 945){
$('.div3').show();
$('.div2').hide();
$('.div1').hide();
}
else if ($('#wrapper').scrollTop() > 465) {
$('.div3').hide();
$('.div2').show();
$('.div1').hide();
}
else {
$('.div3').hide();
$('.div2').hide();
$('.div1').show();
}
});
});
updated fiddle: http://jsfiddle.net/w919y0gb/3/
with this, you could also modify the placement of the "hello1/hello2/hello3" to be in the same position instead of in different places. or you could just have one div in which you modify/replace the text from hello1/hello2/hello3 depending on the scroll position. hope this helps!

That reference site is simply using a background-image set to fixed like so:
FIDDLE
UPDATE
Ok I understand. You would need to do something like this with jquery and $(window).scroll() function:
NEW FIDDLE
using positon: fixed just breaks the element out of the flow of the document and it can't be contained by a parent so you need to use absolute and position it based on the scrollTop to give the appearance that it's fixed.

You could also set the height of your webpage, and then make divs appear as you scroll up or down.
Heres a working example: http://jsfiddle.net/ZyKar/1738/
$(document).scroll(function () {
var y = $(this).scrollTop();
if (y > 0 && y < 400) {
$('#s1').fadeIn();
$('#s3').fadeOut();
$('#s2').fadeOut();
} else if (y > 400 && y < 800) {
$('#s1').fadeOut();
$('#s2').fadeIn();
$('#s3').fadeOut();
}else if (y > 800) {
$('#s3').fadeIn();
$('#s2').fadeOut();
}
});
After you scroll a certain amount of pixels, divs will begin to appear and replace each other.
You may alter the value of y by setting the height of your body in css, as shown in the fiddle. You can then set the pixels conditions in the jQuery to whatever you like.

Related

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();
}
});

rotated image is going out of parent div

I want to rotate the image, but it is going out of parent div.
<div>
<img src="https://cdn.eso.org/images/thumb300y/eso1907a.jpg">
<button class="rotate-button">rotate image</button>
</div>
jquery code
$('.rotate-button').on('click', function() {
var image = $(this).prev('img');
image.className = "rotated_90deg";
});
unrotated state:
rotated state:
how can I keep the image smaller in rotated state, so that it does not go out of parent div?
Try using the solution with scale property
$('.rotate-button').on('click', function() {
var image = $(this).prev('img');
image.className = "rotated_90deg";
});
.rotated_90deg {
transform: rotate(90deg) scale(0.5, 1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<img src="https://cdn.eso.org/images/thumb300y/eso1907a.jpg">
<button class="rotate-button">rotate image</button>
</div>
"tranform rotate" does just that. It retains its original height, and the forging is done in a separate visual layer.
the best thing you can do is set the height of the area where the image rotates equal to the largest side of the image
const img = document.querySelector('img');
const {offsetHeight, offsetWidth} = img;
if(offsetWidth >= offsetHeight) {
img.parentElement.style.height = offsetWidth + 'px';
}
const rotations = [];
const rotateImage = () => {
rotations.push('rotate(45deg)');
img.style.transform = rotations.join(' ');
}
div { display: flex; }
img { transition: .3s; margin: auto; }
button { display: block; margin: auto; position: relative }
<div>
<img src="http://placekitten.com/300/200">
</div>
<button onclick=rotateImage()>Rotate</button>
hmm ... maybe I hastened to answer.
As a solution, "position: relative;" on the button
Put the image inside a container div, give it an id or class and set the overflow to hidden:
.imgContainer{
overflow: hidden;
}
Or if you want the picture to scale so it fits within the div, set max width and height:
.imgContainer img{
max-width: 100%;
max-height: 100%;
}

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);

Sidebar that changes content width

I am currently developing a plugin for existing websites.
Its purpose is to display a sidebar with my content. To that end, the website owner creates an empty div, references my javascript file and calls my code with the ID of the empty div.
My plugin is then creating an iFrame in that empty div and loads its content. It also is responsible for styling the provided div so that it actually is a sidebar: It changes the width and height of that div and attaches it to the right edge of the screen.
So, all of that is basically working - loading my iFrame and styling the div.
The problem is that I am not satisfied with the result.
I have tried two different styles for the div:
Approach 1: float right
I used this CSS:
float: right;
height: 100%;
width: 100px;
The problem with this is that it doesn't change the total width of the rest of the page. In other words, elements on the website with a width: 100% will be shown below my sidebar.
https://jsfiddle.net/DHilgarth/mmzefm14/
Approach 2: Absolute positioning
I used this CSS:
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 100px;
This approach has the problem that my sidebar now simply overlaps the controls from the website.
https://jsfiddle.net/DHilgarth/34hmnw9h/1/
Is there a way to achieve what I want? A sidebar that basically reduces the available size of the body for all elements, except mine?
I have now chosen to actually do exactly what I asked for: I reduce the available width of the body tag.
This is not trivial because of box-sizing, padding, margin, border etc and I am sure I have missed a lot of edge cases but for now, the following logic is working for me:
If box-sizing is border-box: set the right padding of the body element to the width of my sidebar.
Otherwise, set the width of the body element to the width of the body element minus the width of the sidebar. On resize of the window, the width of the body has to be adjusted accordingly.
Code:
function initSidebar() {
loadSidebar("sidebar");
}
// This code would be loaded from a javascript file I provide
function css(element, property) {
return window.getComputedStyle(element, null).getPropertyValue(property);
}
function getSidebarWidth(sidebarElement) {
var boundingRect = sidebarElement.getBoundingClientRect();
return boundingRect.right - boundingRect.left;
}
function styleBorderBoxBody(bodyElement, sidebarElement) {
bodyElement.style.paddingRight = getSidebarWidth(sidebarElement) + "px";
}
function resizeBody(bodyElement, previousWindowWidth, previousBodyWidth) {
var currentWindowWidth = window.innerWidth;
var newBodyWidth = previousBodyWidth - previousWindowWidth + currentWindowWidth;
bodyElement.style.width = newBodyWidth + "px";
return {currentWindowWidth, newBodyWidth};
}
function styleBody(bodyElement, sidebarElement) {
var boxSizing = css(bodyElement, "box-sizing");
if(boxSizing == "content-box" || !boxSizing || boxSizing == "") {
var sidebarWidth = getSidebarWidth(sidebarElement);
var width = bodyElement.clientWidth - sidebarWidth;
bodyElement.style.width = width + "px";
sidebarElement.style.right = (-sidebarWidth) + "px";
var windowWidth = window.innerWidth;
window.addEventListener("resize", function(e) {
var newWidths = resizeBody(bodyElement, windowWidth, width);
width = newWidths.newBodyWidth;
windowWidth = newWidths.currentWindowWidth;
});
} else if(boxSizing == "border-box") {
styleBorderBoxBody(bodyElement, sidebarElement);
window.addEventListener("resize", function(e) { styleBorderBoxBody(bodyElement, sidebarElement); });
}
}
function loadSidebar(sidebarId) {
var sidebarElement = document.getElementById(sidebarId);
sidebarElement.className = "sidebar";
var bodyElement = document.getElementsByTagName("body")[0];
styleBody(bodyElement, sidebarElement);
}
// end: my code
initSidebar();
* {
margin: 0;
padding: 0;
}
html {
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
font: 14px/1.1 Helvetica, Sans-Serif;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
height: 100%;
}
#editor {
width: 100%;
height: 500px;
}
/* this class would be loaded from a CSS file I provide */
.sidebar {
border-color: green;
border-style: solid;
position: fixed;
top: 0;
right: 0;
bottom: 0;
width: 100px;
}
<div id="sidebar"></div>
<h1>Some UI from the existing website</h1>
<textarea id="editor">The text area</textarea>

Make font smaller if there is big text

I have div and within that div text is displayed
<div class="td">
<div class="title main-color">test text</div>
</div>
but if there is big text it goes outside of div. I want to make that if there's big text font to become smaller. How can I achieve that?
JSFIDDLE is here
P.S. I don't want div to grow in height
Demo
https://jsfiddle.net/qjgjg2vh/
Html
<div class="td">
<div class="title main-color">test text</div>
</div>
<div class="td">
<div class="title main-color">test text is bigger now and goes outside of div and dont appears</div>
</div>
CSS
.main-color {
opacity: 0.6;
background: #ffffff;
}
.title {
height: 100%;
width: 470px;
border-radius: 20px;
float: left;
text-align: center;
line-height: 100px;
font-size: 26px;
overflow: hidden;
}
.td {
margin: 60px 0;
height: 100px;
width: 100%;
}
JQUERY
Your original code was getting the character count for ALL paragraphs that matched '.question p'. e.g. If you had two paragraphs, one with ten characters, the other with twenty characters, your JS would run once with a total of thirty, rather than processing each paragraph in turn.
$(function($){
$(".title.main-color").each(function () {
var numChars = $(this).text().length;
if ((numChars >= 1) && (numChars < 20)) {
$(this).css("font-size", "2.2em");
}
else if ((numChars >= 20) && (numChars < 60)) {
$(this).css("font-size", "1.8em");
}
else if ((numChars >= 60) && (numChars < 100)) {
$(this).css("font-size", "1em");
}
else if ((numChars >= 100) && (numChars < 140)) {
$(this).css("font-size", "0.9em");
}
else {
$(this).css("font-size", "0.8em");
}
});
});
You can use javaScript and make the font size smaller and smaller till the time the height of child element with the text fits the height of parent element. I also added visibility:hidden for the text and visibility:visible after fontSize decrease in order to get rid of flashing effect. Remember to put the text into extra element, eg. span. Change the text length to see the effect.
var samp = document.getElementById('samp');
fitFont(samp);
function fitFont(elem){
var child = elem.children[0];
var getFontSize = parseFloat(window.getComputedStyle(child).getPropertyValue('font-size'));
while(child.offsetHeight>elem.clientHeight){
getFontSize -= .1;
child.style.fontSize = getFontSize + 'px';
}
child.style.visibility = 'visible';
}
#samp {
background-color:white;
width:300px;
height:100px;
border:solid 2px #33aaff;
}
#samp span {
display: inline-block;
visibility:hidden;
font-size:50px;
}
<div id="samp">
<span>test text is bigger now and goes outside of div and dont appears test text is bigger now and goes outside of div and dont appears test text is bigger now and goes outside of div and dont appears
</span>
</div>
Of course you could aim for a javascript solution count the letters/words and adjust the font-size accordingly.
$(function() {
var $title= $(".title");
var $numWords = $title.text().split(" ").length;
if (($numWords >= 1) && ($numWords < 10)) {
$quote.css("font-size", "36px");
}
else if (($numWords >= 10) && ($numWords < 20)) {
$title.css("font-size", "32px");
}
else if (($numWords >= 20) && ($numWords < 30)) {
$title.css("font-size", "28px");
}
else if (($numWords >= 30) && ($numWords < 40)) {
$title.css("font-size", "24px");
}
else {
$title.css("font-size", "20px");
}
});
But if you want to use something without Javascript you could do a couple of things.
Unfortunately changing the font-size based on text-length is not possible with css.
Alternatives:
use a horizontal scrollbar (overfloy-x: scroll;)
make the box larger, (any dimension) https://jsfiddle.net/zjaq98Ln/10/
(show the overflow of text) probably not ideal
use text-overflow: https://jsfiddle.net/zjaq98Ln/9/
Try this
.main-color {
opacity: 0.6;
background: #ffffff;
}
.title {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
width: 470px;
border-radius: 20px;
float: left;
line-height: 30px;
font-size: 26px;
}
.td {
margin: 60px 0;
height: 100px;
width: 100%;
}
<div class="td">
<div class="title main-color">test text</div>
</div>
<div class="td">
<div class="title main-color">test text is bigger now, goes outside of div and doesn't appear</div>
</div>
Live demo here: https://jsfiddle.net/grinmax_/zjaq98Ln/11/