I'm trying to figure out the best way to attach two fixed width divs to a fluid center div. I've searched around for an answer to this problem but most people require a 3 column layout to fill the entire width of the screen, whereas I would like a variable amount of whitespace either side.
The intention is that the fluid div will wrap around images scaled to a fixed height but variable width.
Ideally if the edge of the screen is reached the two fixed divs wont go any further. Could this be done with pure css/a framework or is it easier to use javascript? I'm using node.js server-side if it helps.
Right now I'm using inline-block as a way to make it work, but it seems buggy when using percentage widths. It doesn't resize correctly the until page is refreshed, so I was hoping there was a better way.
Center the div containing fluid and fixed elements and, then float:left them.
Demo: http://jsfiddle.net/2utM4/4/
Where is the width coming from? [edit] added offsetWidth.
Here is a javascript approach -- I included an equal-heights routine.
It has the max-width check. The code is commented.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Title</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<style type="text/css">
* { outline:1px dotted #000; } /* all things */
body { padding:0; border:0; margin:0; }
#bodyid { }
#header, #footer { background:#eee; clear:both; }
#middle3 { background:#fee; clear:both; margin:auto; }
#fixedl { background:#efe; float:left; width:50px; }
#fluid1 { background:#eef; float:left; }
#fixedr { background:#efe; float:left; width:50px; }
</style>
<script type="text/javascript">
function f1() { // process center 3 cols
var wfluid1 = document.getElementById("fluid1").offsetWidth;
var wfixedl = wfixedr = 50; // are fixed
var wfluid1 = Math.min(wfluid1, screen.width - wfixedl - wfixedr); // max
var wmiddle3 = wfixedl + wfluid1 + wfixedr;
document.getElementById("middle3").style.width = wmiddle3 + "px";
document.getElementById("fluid1").style.width = wfluid1 + "px";
colsequal(new Array("fixedl", "fluid1", "fixedr")); // equal heights
}
function colsequal(v1) { // makes column heights equal
var h = document.getElementById(v1[0]).offsetHeight;
for (i=1; i<v1.length; i++) { // get maximum height
h = Math.max(h, document.getElementById(v1[i]).offsetHeight); }
for (i=0; i<v1.length; i++) { // make all maximum
document.getElementById(v1[i]).style.height = h + "px"; }
}
</script>
</head>
<body onload="f1();">
<div id="bodyid">
<div id="header">Header</div>
<div id="middle3">
<div id="fixedl">Fixed<br />1</div>
<div id="fluid1">Fluid<br />1<br />2<br />3</div>
<div id="fixedr">Fixed<br />1<br />2</div>
</div>
<div id="footer">Footer</div>
</div><!-- bodyid -->
</body>
</html>
Related
All.
I've been messing with this project for a few days, trying different codes, making some progress, then getting stuck.
The below code is the closest I've come to a working example.
This one counts the WIDTH from the LEFT panel.
I need it to count the WIDTH from the RIGHT panel.
--UPDATED--
I've made it drag from the RIGHT, and it calculates its width from the RIGHT. Unfortunately, the HEIGHT is still not working when the div grows in height, but the width counts.
As you will see when you run the demo below, when you drag the bar, the left panel does not stay attached, along with other issues.
Almost as if it was designed to run one way only.
I know I am missing something here, just not sure what?
Best Viewed In Full Screen.
Thank you.
Wayne
Here is the code
var info = document.getElementById('Info');
var left = document.getElementById('drag-left');
var right = document.getElementById('drag-right');
$(function() {
$(right).resizable({
minHeight: 200,
minWidth: 320
});
$(left).resizable({
minHeight: 200,
minWidth: 320
});
});
// Left Panel
$(right).resizable({
handles: 'w',
resize: function(event, ui) {
// var width = $("body").width() - ui.size.width;
// var height = $("body").height() - ui.size.height;
var width = ui.size.width;
var height = ui.size.height;
$(left).width(left);
$(info).text("Width: " + width + "px; & Height: " + height + "px;");
}
});
/*This is to create the BAR in the middle to grab.
To change which one gets it, change the (e) to (w)
E = Left panel
W = Right Panel*/
.ui-resizable-w {
background-color: black;
}
.ui-resizable-w:hover {
cursor: col-resize;
}
* {
box-sizing: border-box;
}
p {
color: darkslategray;
}
.drag-container {
display: flex;
width:1000px;
padding:5px;
}
[class^=panel] {
padding: 60px 24px;
background-color: whitesmoke;
}
.panel-one {
width: 100%;
flex: 1 1 auto;
}
.panel-two {
width: 60%;
}
#drag-right, #drag-left {
min-height:200px;
min-width:320px;
border:1px double green;
}
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - Simple JS Dragbar</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<link href = "https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css" rel = "stylesheet">
<script src = "https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
</head>
<body translate="no" >
<div class="drag-container">
<div class="panel-one" id="drag-left">
<h2>Panel 1</h2>
<p>Look, everyone wants to be like Germany, but do we really have the pure strength of 'will'? But I know you in the future. I cleaned your poop. Large bet on myself in round one. Take me to your leader! My fellow Earthicans, as I have explained in my book 'Earth in the Balance'', and the much more popular ''Harry Potter and the Balance of Earth', we need to defend our planet against pollution. Also dark wizards.</p>
</div>
<div class="panel-two" id="drag-right">
<h2>Panel 2</h2>
<p>So, how 'bout them Knicks? You guys go on without me! I'm going to go… look for more stuff to steal! Guards! Bring me the forms I need to fill out to have her taken away! Do a flip! Calculon is gonna kill us and it's all everybody else's fault!</p>
</div>
</div>
<div style="float:right; height:30px; width:320px; border:1px double green; padding:40px 4px;">Width: 320px;<br />
<span id="Info">Information Goes Here</span>
</div>
I use this code to check whether user has scrolled to the bottom code or not but it don't work on Google Chrome but it successfully works on Microsoft Edge.
In Google Chrome when i scroll to bottom and again scroll to top then it works but I don't know why.
Here is the code i am using.
<script>
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
alert("bottom!");
}
});
</script>
<!decotype html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div style="height: 4000px">Scroll down!</div>
</body>
</html>
Assuming you use a div to load some data... (Because of #load_data)
You need to get 3 values on scroll:
The scrolled position
The div height
The div scrollable height
This last one is an element property of the real element height, including its overflow.
Additionnally, you need to define what's near the bottom... In pixels.
So... In the below example, I'm faking an Ajax request. Just look for the code you need.
$(document).ready(function() {
// Function to replace Ajax in this demo.
function createContent(n){
var fakeContent = "";
for(i=0;i<n;i++){
fakeContent += i+"<br>";
}
$("#load_data").append(fakeContent);
}
// Simulate initial content...
createContent(100);
// The code you need
var near = 20; // pixels buffer yet to be scrolled when the Ajax triggers.
$("#load_data").on("scroll",function(){
if( $(this).scrollTop() + $(this).height() + near > this.scrollHeight ){
console.log("Faking Ajax...");
createContent(50);
}
});
}); // END ready
#load_data{
height: 150px;
width: 300px;
border: 1px solid grey;
overflow-y:scroll;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
There is 100 (0-99) lines on load.<br>
<div id="load_data"></div>
The problem is when you use margin (top or bottom) you should use .outerHeight(true) instead of .height or the sum of height and margin in this case. If you have padding is the same issue.
$(window).scroll(function(){
if($(window).scrollTop()+$(window).height()>$("h3").outerHeight( true ) ){
alert("bottom!")
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<h3 style="margin-top:2000px">hello world</h3>
</body>
<html>
About .outerHeight()
Get the current computed outer height (including padding, border, and
optionally margin) for the first element in the set of matched
elements or set the outer height of every matched element
.
If you've noticed, it seems that when prepend() is used, the additional elements get piled at the top but the container div is extended downwards.
Comparing with FB's load previous message, you will notice that elements are loaded on top of each other but your view does not change. It is like append() except the container div "seems" to extend upwards.
I've tried doing this to simulate the div extending upwards but failed
var scrolldif = $('#response')[0].scrollHeight-$('#response').scrollTop();
$('#response').scrollTop(scrolldif);
Here is the sample html to try. Just copy/paste/run in browser.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="http://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script>
<script type="text/javascript" src="http://maxcdn.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
</head>
<style type="text/css">
.chatbox div{
height: 100%;
}
#response{
height: 300px;
overflow-y: scroll;
overflow-wrap: break-word;
}
</style>
<script type="text/javascript">
function appendMessage()
{
var data = 'test';
var message = document.createElement('p');
message.innerHTML = data;
$('#response').append(message);
}
function prependMessage()
{
var data = 'test'+Math.floor((Math.random() * 10) + 1);
var message = document.createElement('p');
message.innerHTML = data;
console.log(message.innerHTML);
$('#response').prepend(message);
}
</script>
<body>
<div class="container">
<div class="chatbox">
<div class="col-sm-8 rightP">
<div class="row contents">
<a onclick="return appendMessage()" class="load btn btn-default">Append</a>
<a onclick="return prependMessage()" class="load2 btn btn-default">Prepend</a>
<div class="row msg">
<div id="response" class="msg form-group">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Thank you!
I have finally found the answer but if there are better solutions, do share! It seems that my previous trial actually worked but the position of scrolldif was in reference to the top of container div so I reversed to reference it from bottom like so :
$('#response').scrollTop($('#response')[0].scrollHeight-scrolldif);
In my code above, just do this :
function prependMessage()
{
//this scrollHeight is the total height of div including hidden parts of the
//div caused by overflow BEFORE elements were prepended to it.
var scrolldif = $('#response')[0].scrollHeight-$('#response').scrollTop();
for(var $i = 0;$i<10;$i++)
{
//prepend elements....
}
//this scrollHeight is the total height of div including hidden parts of the
//div caused by overflow AFTER elements were prepended to it.
$('#response').scrollTop($('#response')[0].scrollHeight-scrolldif);
}
Although the 'div' does not extends to the top, but it seems to extend just by adjusting the scrollTop value of the container div. If there are better solutions, do share!
The text in this example moves slightly right before fading out and corrects left after fading back in. I am only seeing this effect on XP(SP3) with Chrome (version 26.0.1410.64 m). The same version of Chrome on Windows7 does not exhibit this behaviour.
The only solution I can find is to reset the bold font to normal before starting the fade but this would not look so good either.
This is part of some larger code and I am looking for a JavaScript solution rather than css.
Thanks.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Fade moves text horizontally in Chrome with Windows XP</title>
<style type="text/css">
body {font-family: Arial; font-size:12px; font-weight:bold;}
</style>
<script type="text/javascript">
function setOpacity(id,level) {
var a = document.getElementById(id);
if(a) {
a.style.opacity = level;
}
}
var duration = 1000;
var steps = 22;
function fadeIn(id){
for (i = 0; i <= 1; i += (1 / steps)) {
setTimeout("setOpacity('" + id + "'," + i + ")", i * duration);
}
}
function fadeOut(id) {
for (i = 0; i <= 1; i += (1 / steps)) {
setTimeout("setOpacity('" + id + "'," + (1 - i) + ")", i * duration);
}
}
</script>
</head>
<body>
<div id="fade">
This text moves slightly to the right before fading out and resets itself back to the left after fading back in.
<br />
This text moves slightly to the right before fading out and resets itself back to the left after fading back in.
</div>
<p onclick="fadeOut('fade')">Click to fade out</p>
<p onclick="fadeIn('fade')">Click to fade in</p>
</body>
</html>
I have a HTML page & when a link is clicked I am trying to make a popup element(just a div box that appears over the link) appear above the link that was clicked. I use javascript to do this, but my problem is that the popup element gets positioned below the link when it should be above the link.
Do you know what I am doign incorrectly & how I can fix it?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><!-- InstanceBegin template="/Templates/homepage.dwt" codeOutsideHTMLIsLocked="false" -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style type="text/css" media="all">
<!--
html, body, div, form, fieldset, legend, label, img { margin: 0; padding: 0; } table { border-collapse: collapse; border-spacing: 0; } th, td { text-align: center; } h1, h2, h3, h4, h5, h6, th, td, caption { font-weight:normal; } img { border: 0; }
body { padding: 20%; background-color: green; }
.container { background-color: white; }
.newEle { width: 100px; height: 100px; background-color: red; }
-->
</style>
<script type="text/javascript">
function getOffset( el )
{
var _x = 0;
var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
{
_x += el.offsetLeft - el.scrollLeft;
_y += el.offsetTop - el.scrollTop;
el = el.parentNode;
}
return { top: _y, left: _x };
}
function onClick( n, ele )
{
// Should display a popup box just above the HTML element called "ele"
// but what actually happens is that the box is displayed below the element
// called "ele"
var infoBox = document.createElement("div");
infoBox.style.zIndex = "5";
//infoBox.offsetRight = ele.offsetRight;
//infoBox.offsetBottom = parseInt(ele.offsetBottom, 10) - 200 + "px";
infoBox.style.x = getOffset( ele ).left + "px";
infoBox.style.y = getOffset( ele ).top - 200 + "px";
infoBox.style.width = "200px";
infoBox.style.height = "200px";
infoBox.style.backgroundColor = "blue";
infoBox.innerHTML = "Hello";
document.body.appendChild( infoBox );
}
</script>
</head>
<body>
<div class="container">
<a class="newEle" onclick="onClick(1,this)">Create New Element</a>
</div>
</body>
</html>
add this to your css.
.container, .newEle {display: block; float: left;}
Then position your elements absolutely.
(Aside from Carl Griffiths post take a look on this)
Inspecting your code, the reason why it is below your link is:
Your appending the new element after your div.
You said you have a x and y style. But it is not applying on that element.
(Use firebug for FF or in Chrome use developer-tools)
Let say you successfully add the position style on the new element.
Your next problem is, it will not visible on the page.
What I mean is, if you set the top position to -200px it will relatively position
to your body not in your link.
Possible Fix:
Instead of using document.body.appendChild( infoBox );
Add an id to your div like id="container". Then replace your append with this.
var parentContainer = document.getElementById('container');
parentContainer.insertBefore(infoBox,parentContainer.firstChild);
I'm not pretty sure about your infoBox.style.x but instead you can use this infoBox.style.left = "0px;" and infoBox.style.top = "-200px" then you must use positioning e.g. relative/absolute
If you follow the second option you must properly set the CSS style of your div. Specially this body { padding: 20%; background-color: #CCCCCC; } If you find it difficult to understand my explanation. Here a sample code (jsfiddle) it is not as perfect as you want. But you can use enhance on your needs.
I've got a component that might make this simpler - it's not as complete as framework would be, but it's pretty good at what it does:
http://depressedpress.com/javascript-extensions/dp_panelmanager/
It basically creates "panels" out of HTML elements (either existing or generated) and provides methods to work with them. Position, Size, Opacity, simple animations, collision detection, bearing, etc. It's definately got holes, but it's come in handy.
One of the examples is a simple "popup definitions" thing that should be pretty easy to modify to fit your needs.
Basically you create panels for your popups and also turn your click targets into panels (the example shows how you do that with minimal code). Then your onClick event handler might have something like this:
// Set the Popup panel to the same position as the clicked element.
PopPanel.setPosition(this.getPosition());
// Shift the position of the popup panel up 210 pixels
PopPanel.shiftPosition([-210, 0]);
// Show the panel
PopPanel.setDisplay("show");
// Fade the panel in (Animate opacity)
PopPanel.setOpacity(100, 0 , 200);
Of course you're not too far off - and the advise already given will probably fix your current problem.