<link rel="stylesheet" type="text/css" href="reset.css" />
<style type="text/css">
body { position: relative; }
.contain { position:relative; overflow: hidden; width: 80%; height: 100%; margin: 0 auto; }
.box {
background-color: #F0F0F0;
color: #888;
font-family: Arial, Tahoma, serif;
font-size: 13px; }
.box p { padding: 10px; }
.box span {
float: left;
font-size: 26px;
font-weight: bold; }
div.alt { background-color: #CCC; }
</style>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript">
var myFluidGrid = {
COLNUMBER : 2, // Minimum column number.
COLMARGIN : 10, // Margin (in pixel) between columns/boxes.
COLWIDTH : 240, // Fixed width of all columns.
doLayout : function() {
var self = this;
var pointer = 0;
var arr = [];
var columns = Math.max(this.COLNUMBER, parseInt($('body').innerWidth() / (this.COLWIDTH + this.COLMARGIN)));
$('.box').css('position', 'absolute').css('width', this.COLWIDTH + 'px');
$('.box').each(function() {
var tempLeft = (pointer * (self.COLWIDTH + self.COLMARGIN));
$(this).css('left', tempLeft + 'px');
var tempTop = 0;
if (arr[pointer]) { tempTop = arr[pointer]; }
$(this).css('top', tempTop + 'px');
arr[pointer] = tempTop + $(this).outerHeight() + self.COLMARGIN;
pointer++;
if (pointer === columns) { pointer = 0; }
});
}
};
$(window).ready(function() {
myFluidGrid.doLayout();
}).resize(function() {
myFluidGrid.doLayout();
});
</script>
<div class="contain">
<div class="box">This is box number 1...</div>
<div class="box">This is box number 2...</div>
<div class="box">This is box number 3...</div>
</div>
Demo of current code: http://grahamthomas.me/temp/test.html
Trying to get the above grid to remain centered in the window no matter its size. I currently have it roughly centered, but when the window size is adjusted, the centering becomes untrue until the new column is populated with content (i.e. when the dynamic grid is between columns--larger than 3 columns, but no quite 4).
I'm not great at JS, but my logic is:
create a 100% wrapper (which would mimic the body.innerWidth
dimension in the JS)
create a centered wrapper inside this (80% for example)
place the content in the centered wrapper
once the 100% wrapper is large enough to handle an additional column, append the new div within the centered wrapper
You can clearly see the overflow:hidden property 'run over' the right-most boxes when dragging the window smaller. I assume from this, the window width isn't being calculated properly. I tried variants of var columns, like:
var columns = Math.max(this.COLNUMBER, parseInt(($('body').innerWidth() * 0.8)/ (this.COLWIDTH + this.COLMARGIN)));
..which keeps the columns within the window, but still isn't a proper center.
I've been looking at this for a while, anyone have any ideas?
Thanks
No JavaScript required:
<html>
<head>
<style>
body {
text-align: center;
}
div.main {
position: absolute;
top: 100px;
left: 50%;
margin-left: -40%;
width: 80%;
}
div.main div.block {
height: 180px;
width: 180px;
background: #a00;
float: right;
margin: 10px;
}
</style>
</head>
<body>
<div class="main">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
</body>
</html>
Related
If you take a look at KIOSK WEBSITE HERE they have the 'WE ARE OPEN" circular type in javascript (I know how to do that) but what I don't know is how to achieve that when scrolling. Like how does the text move when scrolling up or down. How do you get that in HTML/CSS/JS ?
View the code I worked on here https://codepen.io/noel_emmanuel/pen/WJxRZW
HTML:
<!--just a container used to position in the page-->
<div class="container">
<!--the holders/targets for the text, reuse as desired-->
<div class="circTxt" id="test"></div>
</div>
<!--I told you it was simple! :)-->
CSS:
body {
background: #111;
}
.container {
/*centers in the container*/
text-align: center;
}
div.circTxt {
/*allows for centering*/
display: inline-block;
/*adjust as needed*/
margin-bottom: 128px;
color: whitesmoke;
}
JS:
function circularText(txt, radius, classIndex) {
txt = txt.split(""),
classIndex = document.getElementsByClassName("circTxt")[classIndex];
var deg = 360 / txt.length,
origin = 0;
txt.forEach((ea) => {
ea = `<p style='height:${radius}px;position:absolute;transform:rotate(${origin}deg);transform-origin:0 100%'>${ea}</p>`;
classIndex.innerHTML += ea;
origin += deg;
});
}
circularText("WE ARE OPEN", 100, 0);
OPEN FOR SUGGESTIONS.
You could rotate this on a scroll event. This simply rotates the div depending on how far from the top of the page you have scrolled.
I added a height and width to the text, as well as positioned it fixed to see the effect.
function circularText(txt, radius, classIndex) {
txt = txt.split(""),
classIndex = document.getElementsByClassName("circTxt")[classIndex];
var deg = 360 / txt.length,
origin = 0;
txt.forEach((ea) => {
ea = `<p style='height:${radius}px;position:absolute;transform:rotate(${origin}deg);transform-origin:0 100%'>${ea}</p>`;
classIndex.innerHTML += ea;
origin += deg;
});
}
circularText("WE ARE OPEN", 100, 0);
$(document).ready(function(){
$(window).scroll(function(e){
rotateText();
});
function rotateText(){
var scrolled = $(window).scrollTop();
$('div.circTxt').css('transform','rotate('+scrolled+'deg)');
}
});
body {
background: #111;
}
.container {
/*centers in the container*/
text-align: center;
height: 4000px;
}
div.circTxt {
/*allows for centering*/
display: inline-block;
/*adjust as needed*/
margin-bottom: 128px;
color: whitesmoke;
position: fixed;
height: 200px;
width: 200px;
transform-origin: 0% 59%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!--just a container used to position in the page-->
<div class="container">
<!--the holders/targets for the text, reuse as desired-->
<div class="circTxt" id="test"></div>
</div>
<!--I told you it was simple! :)-->
I am making a page where there should be content on the left side and commercials in divs on the right side. The height of the left sides div is unknown. I want to add as many commercial divs as possible on the right side without making the height of the right side taller than the left side.
I have set the right sides div height equal to left sides height and then I have added overflow: hidden on the right sides div so that the commercial divs are being cut off. I don't want my commercial divs to be cut off so I would like to remove the one that is being cut off.
Here is my code https://jsfiddle.net/p9dmzoa3/
You can try below code, this will remove all those commercials DIV, which are getting cut-off :
$(document).ready(function() {
$(".right_side").css("height", $(".left_side").height());
$commercialDivs = $(".right_side").children("div.commercials");
$rightSideDivHeight = $(".right_side").height();
$tempHeight = 0;
for(var i=0;i<$commercialDivs.length;i++){
$tempHeight += $commercialDivs[i].clientHeight;
if($tempHeight>$rightSideDivHeight){
$commercialDivs[i].remove();
}
}
});
Something like this should do the thing.
$(document).ready(function() {
$(".right_side").css("height", $(".left_side").height());
var j = $(".right_side").children("div").length;
for (var i = 1; i < j; i++) {
if ((($('.right_side').offset().top + $(".right_side").height()) - ($('.right_side div:last-child').offset().top + $(".right_side div:last-child").height())) < 0) {
$(".right_side div:last-child").remove();
} else {
break;
}
}
});
div.left_side {
display: inline-block;
}
div.right_side {
display: inline-block;
float: right;
overflow: hidden;
}
div.left_side_content {
height: 30px;
margin-top: 10px;
background-color: green;
}
div.commercials {
height: 50px;
margin-top: 10px;
background-color: forestgreen;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content" style ="width: 430px; background-color: lightblue; padding: 5px;">
<div class="left_side" style ="width: 200px; background-color: tomato; padding: 5px;">
<div class="left_side_content">content</div>
<div class="left_side_content">content</div>
</div>
<div class="right_side" style ="width: 200px; background-color: orange; padding: 5px;">
<div class="commercials">commercials</div>
<div class="commercials">commercials</div>
<div class="commercials">commercials</div>
<div class="commercials">commercials</div>
<div class="commercials">commercials</div>
<div class="commercials">commercials</div>
</div>
</div>
I have a label I'm attempting to generate. It has the following structure.
.name-box { width: 400px; background-color: #efefef; border: 1px solid #000; overflow: hidden; white-space: nowrap; }
.last-name { font-size: 26px; display:inline; overflow: hidden;}
.first-name { display:inline; overflow: hidden;}
<div class="name-box">
<div class="last-name">McDonald-OrAReallySuperDuperLongLastName</div>
<div class="first-name">David</div>
</div>
What I'm wanting to do is change the text size of the first name, based on the length of the last name. If the name is "Venckus-Stringfellow" and I only have a little bit of space left I'd like the text size of the first name to be around 7px. But if the last name is "Le", then I'd want the first name to have a text size of 26px -- granted that having a text size of 26px still allows the first name to fit on the 600px that my div has to fill the label. How can I do this with HTML/CSS (if I MUST use Javascript then that's fine, was trying to avoid it though) ?
Javascript that uses the length of the last name in a mathematical equation to set the first names size. This is a very simple example and you'd need to change it if you wanted it to be exponential and you should probably set high and low bounds that it can't go below.
var lastNameText = document.querySelector('.last-name').textContent;
var firstName = document.querySelector('.first-name');
firstName.style.fontSize = (120 / lastNameText.length) + "px";
.name-box { width: 600px; }
.last-name { font-size: 26px; }
.first-name: { font-size: 26px; }
<div class="name-box">
<div class="last-name">McDonald</div>
<div class="first-name">David</div>
</div>
You're going to need javascript here, unfortunately. You can get close using viewport percentages, but that applies to the whole viewport. And it would only be for one container, not a preceding container. What you are going to need to do is create an algorithm that updates the font sizes, and run it everytime you load HTML/text into those div's.
Something like this should get you started:
function loadNames(var firstName, var lastName) {
//GET THE LENGTH OF THE LASTNAME STRING
var len = lastName.length;
var factor = .7; //CUSTOMIZE THIS TO DO YOUR SIZING BASED ON THE FONT
var fontSize = Math.ceil(factor * len); //GET THE NEW FONT SIZE, BASED ON THE LENGTH AND FACTOR, AND ROUNDED UP
//SET THE TEXT OF THE NAMES
$('firstName').Text(firstName);
$('lastName').Text(lastName);
//SET THE FONT SIZES
$('firstName').css({ 'font-size': fontSize + 'px;' });
$('lastName').css({ 'font-size': fontSize + 'px;' });
}
CSS solution unfortunately is not possible. It's not possible to select partial text inputs, and there's some calculation required that cannot be done with CSS at this point, in this age.
But javascript.. Were you looking for something like this OP?
$(document).on("ready", function(){
var ratio = 20;
$(".name").keydown(function(){
var input_length = $(this).val().length / ratio;
var new_size = (2 - input_length < 1 ? 1 : 2 - input_length);
$(this).css("font-size", new_size+"em");
});
});
input {
width: 40em;
margin: 0 auto;
display: block;
padding: 15px;
}
.main-wrapper {
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-wrapper">
<input class="name" type="text" placeholder="Enter name" />
</div>
This is another approach how You could achieve the result. Maybe it's possible to do not use table at all but each div should use display:inline-block; property.
$scalingL = $('.last-name').width();
$scalingF = $('.first-name').width();
$('.first-name').css('font-size',($scalingL / $scalingF * 26));
.name-box { width: 600px; background-color: #efefef; border: 1px solid #000; overflow: hidden; white-space: nowrap; }
.last-name { font-size: 26px; overflow: hidden; display:inline-block;}
.first-name { font-size: 26px; display:inline-block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="name-box">
<table>
<tr>
<td>
<div class="last-name">McDonald-OrAReallySuperDuperLongLastName</div>
</td>
</tr>
</tr>
<td>
<div class="first-name">Something</div>
</td>
</tr>
</table>
</div>
Try this:
<style type="text/css">
.name-box{
width:auto;
overflow:auto;
}
#first-name{
display:inline-block;
width:auto;
clear:both;
float:left;
font-size:1px;
}
#last-name {
display:inline-block;
width:auto;
clear:both;
float:left;
font-size:26px;
}
</style>
<div class="name-box">
<div id="last-name">McDonalds</div>
<div id="first-name">David</div>
</div>
<script type="text/javascript">
var ln = document.getElementById("last-name");
var fn = document.getElementById("first-name");
for ( i = 1; ln.offsetWidth>fn.offsetWidth; i+=.5)
{
fn.style.fontSize=(i)+"px";
}
</script>
<style type="text/css">
.name-box{
width:auto;
overflow:auto;
}
#first-name{
display:inline-block;
width:auto;
clear:both;
float:left;
font-size:1px;
}
#last-name {
display:inline-block;
width:auto;
clear:both;
float:left;
font-size:26px;
}
</style>
<div class="name-box">
<div id="last-name">McDonalds</div>
<div id="first-name">David</div>
</div>
<script type="text/javascript">
var ln = document.getElementById("last-name");
var fn = document.getElementById("first-name");
for ( i = 1; ln.offsetWidth>fn.offsetWidth; i+=.5)
{
fn.style.fontSize=(i)+"px";
}
</script>
I want to transition the background colour of a fixed header element on scroll. So as a user scrolls down a full page block website, the header subtly changes to complement the block colours. I have almost achieved this on a Pen, however I can't quite work out how to measure how much has been scrolled as a flag for when to change.
Some extra info: The scroll amount to change at is 400px. The background colours are stored and fetched in an array. For reference my jQuery code is below:
$(document).ready(function(){
var bgArray = ["#252525","#333333","#454545","#777777"];
var scrollHeight = 400;
var scrolled = $(window).scrollTop(); //What is this measuring?
$(window).scroll(function() { //Can these conditions be neatened into one function?
if(scrolled < scrollHeight) {
$('header').css('background', bgArray[0]);
}
if(scrolled > scrollHeight) { // i.e more than 400px
$('header').css('background', bgArray[1]);
}
// and so on (800, 1200...)
})
})
Please refer to the Pen for full code. Any suggestions are greatly appreciated!
Updated Solution (2019)
To set a background for the header based on the current block in view below the header while scrolling:
because header has fixed position, we can get the amount by which window has scrolled by using $header.offset().top,
(index of the current block in view) is the ratio of (the amount by which window has scrolled) to the (height of each block),
now adjusting for the height of the header, the index of the current block in view is Math.floor(($header.offset().top + headerHeight) / sectionHeight).
See simplified demo below:
$(function() {
var $header = $('header'),
$window = $(window),
bgArray = ["#252525", "red", "blue", "green"],
headerHeight = 50,
sectionHeight = 400;
$window.scroll(function() {
$header.css('background', bgArray[Math.floor(($header.offset().top + headerHeight)
/ sectionHeight)]);
});
});
:root {
--header: 50px; /* header height */
--block: 400px; /* block height */
}
* {
box-sizing: border-box; /* include padding in width / height calculations */
}
body {
margin: 0; /* reset default margin of body */
}
header {
height: var(--header); /* sets height of header */
position: fixed;
top: 0;
left: 0;
width: 100%;
color: #FFF;
padding: 12px 0;
background: #252525; /* initial background */
transition: background 1s ease;
}
.container {
margin: 0 auto;
}
.wrap>div {
height: var(--block); /* sets height of each block */
text-align: center;
}
p {
margin: 0; /* reset margin of p */
}
.block-1 {
background: #27AACC;
color: #FFF;
}
.block-2 {
background: #668E99;
color: #FFF;
}
.block-3 {
background: #4AFFC1;
color: #444;
}
.block-4 {
background: #FF8F8A;
color: #FFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<div class="container">
Website Title.
</div>
</header>
<div class="wrap">
<div class="block-1">
<div class="container">
<p>This pen was made to solve a problem on a project...</p>
</div>
</div>
<div class="block-2">
<div class="container">
<p>...I needed a sticky header with thr right bg colour.</p>
</div>
</div>
<div class="block-3">
<div class="container">
<p>But this conflicted with the footer, which was the same colour...</p>
</div>
</div>
<div class="block-4">
<div class="container">
<p>So the solution was to subtley change the header's bg on scroll</p>
</div>
</div>
</div>
Original Solution
Check the top of each block with respect to how much the window has been scrolled (scrollTop) using $(window).scrollTop() > $('.block-1').offset().top. So now we can use this to change color on entering the block - see demo below:
$(document).ready(function() {
var $header = $('header'),
$window = $(window),
bgArray = ["#252525", "#333333", "#454545", "#777777"],
headerHeight = $header.outerHeight();
$window.scroll(function() {
for (var i = 1; i < 5; i++) {
if ($window.scrollTop() + headerHeight > $('.block-' + i).offset().top) {
$header.css('background', bgArray[i - 1]);
}
}
});
});
#import url('https://fonts.googleapis.com/css?family=Roboto:300,400,700');
body {
font-family: 'Roboto', sans-serif;
font-size: 30px;
font-weight: 300;
margin-top: 0;
}
header {
width: 100%;
height: 50px;
line-height: 50px;
position: fixed;
font-size: 24px;
font-weight: 700;
color: #FFF;
padding: 12px 0;
margin: 0;
background: #252525;
transition: background 1s ease;
}
.wrap {
padding-top: 74px;
margin: 0;
}
.container {
width: 960px;
margin: 0 auto;
overflow: hidden;
}
.block-1,
.block-2,
.block-3,
.block-4 {
height: 400px;
text-align: center;
}
p {
margin-top: 185px;
}
.block-1 {
background: #27AACC;
color: #FFF;
}
.block-2 {
background: #668E99;
color: #FFF;
}
.block-3 {
background: #4AFFC1;
color: #444;
}
.block-4 {
background: #FF8F8A;
color: #FFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<div class="container">
Website Title.
</div>
</header>
<div class="wrap">
<div class="block-1">
<div class="container">
<p>This pen was made to solve a problem on a project...</p>
</div>
</div>
<div class="block-2">
<div class="container">
<p>...I needed a sticky header with thr right bg colour.</p>
</div>
</div>
<div class="block-3">
<div class="container">
<p>But this conflicted with the footer, which was the same colour...</p>
</div>
</div>
<div class="block-4">
<div class="container">
<p>So the solution was to subtley change the header's bg on scroll</p>
</div>
</div>
</div>
Note that this solution needlessly loops through the sections on each scroll update called by the browser - and I don't like the look of it.
you are using scrolled as a fixed variable you should use it directly in your condition
this will make it dynamic for all elements inside wrap div
$(document).ready(function(){
var bgArray = ["#252525","#333333","#454545","#777777"];
$(window).scroll(function() {
for(var i = 1; i < bgArray.length; i++) {
if ($(window).scrollTop() > $('.wrap div:nth-child(' + i + ')').offset().top) {
$('header').css('background', bgArray[i-1]);
}
}
});
})
Try Like this:
$(document).ready(function(){
var bgArray = ["#252525","#333333","#454545","#777777"];
var scrollHeight = 400;
$(window).scroll(function() {
var scrolled = $(window).scrollTop();
var index=Number((scrolled/scrollHeight).toFixed());
if(bgArray[index]!=undefined)
$('header').css('background', bgArray[index]);
});
})
This is current scroll, so it should be inside: $(window).scrollTop()
I want to calculate the scrolled distance of a div element within another div element. I am using offsetTop for that, but it always returns 0 in my code. I am unable to figure out where I am making the mistake.
function getScrollVal() {
console.log(window.pageYOffset);
var wrap = document.getElementById("wrapper");
console.log(wrap.id);
console.log(wrap.offsetParent.id);
var parent = wrap.offsetParent;
console.log("scrollTop: " + wrap.scrollTop + " scrollLeft: " + wrap.scrollLeft);
console.log("offsetTop: " + wrap.offsetTop + " offsetLeft: " + wrap.offsetLeft);
/*
var xx = wrap.offsetLeft;
var yy = wrap.offsetTop;
while(wrap = wrap.offsetParent){
xx += wrap.offsetLeft;
yy += wrap.offsetTop;
}
*/
}
body, html {
margin: 0;
padding: 0;
}
#contain {
position: relative;
width:100%;
height: 100vh;
background: yellow;
overflow: auto;
}
#wrapper {
width: 85%;
margin: 0 auto;
background: red;
}
.full {
height: 100vh;
width: 85%;
margin: 0 auto;
}
#one { background:#222;}
#two{ background:#00c590;}
#three{ background:#3429c5;}
#four{background:#bbb;}
#b {
position: fixed;
z-index: 1000;
top: 30px;
left: 30px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<div id="contain">
<div id="wrapper">
<div id="one" class="full"></div>
<div id="two" class="full"></div>
<div id="three" class="full"></div>
<div id="four" class="full"></div>
</div>
</div>
<button id="b" type="button" onClick="getScrollVal();" value="click me">Press me</button>
</body>
</html>
I have tried the js code inside the comment. That one is not providing a fruitful result. Thanks in advance.
Since the element #contain is the overflow element, you can try get the scrollTop like this:
console.log("scroll top:", document.getElementById('contain').scrollTop);
From MDN:
An element's scrollTop is a measurement of the distance of an element's top to its topmost visible content. Element.scrollTop