is it even possible to expand a (horizontal) list's background with ajax? - css

I've got a list with list-style-none which needs to be able to add new items to itself via Ajax and have the background expand appropriately when it does. Adding via Ajax is easy, but every solution I try for the background fails me. I don't know if it's even possible; is it? I'm using a grid like this one:
http://jqueryui.com/demos/sortable/#display-grid
Both WebKit and Firebug are showing me skinny, empty bars when I hover over the enclosing divs and/or the enclosing ul tag. It appears that the minute you set a list loose with list-style-none and float:wherever, you give up control over its background. But that can't be right.

This is something I've run into a number of times. The problem is that floated elements aren't part of the normal box model, so they don't cause their parent elements to expand unless their parent elements are also floated. So if possible, float the ul or containing div.
Edit:
See quirksmode for another css-only workaround.

Could you provide a sample of your code? Also, why does the list have display:none set?
For instance, should be as simple as this:
HTML:
<ul id="dest"></ul>
JS:
// Simplified example, most likely wrapped in $.ajax
// This is the AJAX response function
function(data, response) {
var items = json.parse(data);
$.each(items, function() {
// Assumes item has a name property
$('#dest').append($('<li>' + this.name + '</li>'));
});
}
Should be just that simple. You shouldn't need the hide the list initially, as you can simply append list items and have the display update appropriately.
Hope that helps.

You need to explicitly set the width and height for the area.
Check out this link for Horizontal Scrolling: http://valums.com/scroll-menu-jquery/
Here is the script:
$(function(){
//Get our elements for faster access and set overlay width
var div = $('div.sc_menu'),
ul = $('ul.sc_menu'),
// unordered list's left margin
ulPadding = 15;
//Get menu width
var divWidth = div.width();
//Remove scrollbars
div.css({overflow: 'hidden'});
//Find last image container
var lastLi = ul.find('li:last-child');
//When user move mouse over menu
div.mousemove(function(e){
//As images are loaded ul width increases,
//so we recalculate it each time
var ulWidth = lastLi[0].offsetLeft + lastLi.outerWidth() + ulPadding;
var left = (e.pageX - div.offset().left) * (ulWidth-divWidth) / divWidth;
div.scrollLeft(left);
});
});
Basically, you need to update the ulWidth and divWidth when you add the new item.
Then just set the background image to repeat horizontally and you should be set.
ul.sc_menu {background:transparent url(image.png) repeat scroll 0 0;height:100px}
Note: You will need to set the height; otherwise you will not see the background because the li are floated.

For dealing with the float element, maybe you should know it's characteristic, gotcha, and how to deal with it.
See the links below, it also have demo, so you can understand the concept:
http://www.smashingmagazine.com/2009/10/19/the-mystery-of-css-float-property/
http://www.smashingmagazine.com/2007/05/01/css-float-theory-things-you-should-know/
http://aloestudios.com/2009/12/goodbye-overflow-clearing-hack/
and
http://aloestudios.com/misc/overflow/

Related

Sticky navigation element jumps during scroll

In Firefox especially, I've run into an issue I can't figure out how to fix.
On the following page, when scrolling down the page jumps several times - mainly on smaller screens where the page doesn't have its full size displayed. You can replicate this issue by making your browser smaller than the page so you have to scroll.
It's on this page: http://www.nucanoe.com/frontier-accessories/
If I disable the position:fixed on the navigation selector, it fixes the issue - but we need the navigation to be sticky. Is there a solution to fix this? I'm thinking we may need to use jQuery somehow.
Thanks in advance!
After seeing you asking for help on another answer, I will try and explain more clearly for you.
The Problem
Your problem is when you add position:fixed to the navigation bar, it removes it from its place and sticks it at the top of the page. This is why the rest of your content jumps up - because the navigation bar is not where it was anymore.
How To Fix
You can get around this by wrapping your navigation element in a new div - let's call it nav-wrapper - and set its height to the same as your navigation element. These are known as placeholder elements. This new wrapper and your original navigation bar must always be the same height for the 'jump' to disappear.
<div class="nav-wrapper" style="height:80px;"> <-- add this
<div class="your-original-nav" style="height:80px"></div>
</div> <!-- add this
Now, when you set the navigation bar to fixed and it disappears to the top, the new wrapper we created with the same height keeps the page's content the same. When the fixed class has been removed, it sits back in the wrapper again, without pushing the content down.
A Suggestion
From what I can see on your site, there will be a big gap where the navigation bar was until the new fixed navigation reaches that point and covers it. What you want, is a little jQuery to figure out where to make the navigation fixed and where to hide it. I'll explain:
// cache the element
var $navBar = $('.your-original-nav');
// find original navigation bar position
var navPos = $navBar.offset().top;
// on scroll
$(window).scroll(function() {
// get scroll position from top of the page
var scrollPos = $(this).scrollTop();
// check if scroll position is >= the nav position
if (scrollPos >= navPos) {
$navBar.addClass('fixed');
} else {
$navBar.removeClass('fixed');
}
});
You may want to add further functionality to this example, as it is very, very basic. You would probably want to recalculate the offsets on window resize as one addition.
A Demo
This is a little demo which might help you - I was bored and feeling helpful :)
Made it this way now: Added an element before the nav:
<div class="nav-placeholder"></div>
And the jquery:
<script type="text/javascript">
$(document).on("scroll",function(){
if($(document).scrollTop()>150){
$(".nav-placeholder").height($(".nav").outerHeight());
} else {
$(".nav-placeholder").height(0);
}
});
</script>
When I scroll down to 150 the placeholder gets the height of the nav, when i scroll up again I set it's height to 0.
Here is a fiddle: https://jsfiddle.net/herrfischerhamburg/562wu62y/
You need to have a placeholder when your nav goes from relative to fixed.
Therefore you need to make a new div.
jQuery(".nav").wrap('<div class="nav-placeholder"></div>');
jQuery(".nav-placeholder").height(jQuery(".nav").outerHeight());
jQuery(".nav").wrapInner('<div class="nav-inner"></div>');
Remember to change ".nav", "nav-inner" and "nav-placeholder" to your desire.
For a fully functional sticky nav, check my website: http://www.swegre.se/
I solved the problem differently so on firefox as you can see in logs it scroll up itself so to stop this scrolling I made simple statement
$(document).ready(function () {
var header = $('#left-menu');
var offset = header.offset().top;
var up = true;
$(window).scroll(function () {
var scroll = $(window).scrollTop();
console.log(scroll + ' ' + offset )
if (scroll >= offset) {
header.addClass('sidebar-sticky');
if (up){
$(window).scrollTop(offset);
up=false;
}
} else {
up=true;
header.removeClass('sidebar-sticky');
}
});
});
that solution work for me when I can't specify height of div's I use.

Wrap text from bottom to top

Anybody know how I could wrap the text in reverse order, from bottom to top?
I attached an example image.
[][http://i.stack.imgur.com/RVsIG.jpg]
Instead of breaking the line after it is full and having an incomplete line at the end, I need to brake somehow from bottom to top, so bottom lines are full and top line is incomplete.
I would not recommend using exotic CSS attributes which aren't even in Chrome & Firefox yet. The best cross-browser solution is to handle this in Javascript when the document loads. Here's a sketch of how to do that:
$(function() {
$(".title").each(function(i,title) {
var width = 0;
var originalHeight = $(title).height();
var spacer = $('<div style="float:right;height:1px;"/>').prependTo(title);
while (originalHeight == $(title).height()) {
spacer.width( ++width );
}
spacer.width( --width );
});
});
Working JSFiddle is here: http://jsfiddle.net/zephod/hfuu3m49/1/
6 years later, but fret not! I have found a pure CSS solution!
Turns out you can achieve this result with flexbox, but it's not obvious or very straight forward. This is what I started out with:
I want the header to be "bottom-heavy", the same effect as you describe in the question.
I began by splitting up my string by whitespace and giving them each a <span> parent. By using flex-wrap: wrap-reverse, and align-content: flex-start. You will achieve this:
Oh no! Now the order is messed up! Here comes the trick. By reversing both the order in which you add spans to the HTML and the direction order of flex with 'flex-direction: row-reverse', you actually achieve the "pyramid-shaped" upwards overflow effect you desire.
Here is my (simplified) code, using react and react-bootstrap:
<Row className='d-flex flex-wrap-reverse flex-row-reverse align-content-start'>
{props.deck.name
.split(' ')
.reverse()
.map(word => (
<span className='mr-1'>{word}</span>
))}
</Row>
There is no general css solution for it. You must have to utilize help of any language.
This is one of the solution using PHP:
<?php
$str= "This is what I want to achieve with your help";
$str = strrev($str);
$exp = str_split($str,18);
$str = implode(">rb<", $exp);
echo strrev($str);
?>
Well, if that is depending on the text, then you can try something like a word replacer. For example
var words = "This is what I want to achieve";
var newWords.replace("what", "what <br />"); // note the line break
document.write(newWords);
Here is a fiddle for you: http://jsfiddle.net/afzaal_ahmad_zeeshan/Ume85/
Otherwise, I don't think you can break a line depending on number of characters in a line.
Wrap and Nowrap will be rendered by the client-browser, so you can not force the browser to wrap from bottom to top. but you can do that with javascript or asp.
This is not a formal solution for this problem. But see if this helps.
The HTML CODE
<div id="mydiv">
I can imagine the logic behind the code having to detect what is the last line, detect the div size, and the font size... then measure how many characters it can fit and finally go to the above line and insert the break where necessary. Some font families might make this harder, but trial and error should solve the issue once the basic code is set..
</div>
CSS:
#mydiv
{
width:1000px;
line-height:18px;
font-size:20px;
text-align:justify;
word-break:break-all;
}
Here setting the div width around 50 times that of the font-size will give you the precise result. Other width values or font values might slightly disorient the last line, giving some blank space after the last character.(Could not solve that part, yet).
JQuery:
$(document).ready(function(){
//GET the total height of the element
var height = $('#mydiv').outerHeight();
//Get the height of each line, which is set in CSS
var lineheight = $('#mydiv').css('line-height');
//Divide The total height by line height to get the no of lines.
var globalHeight = parseInt(height)/parseInt(lineheight);
var myContent = $('#mydiv').html();
var quotient = 0;
//As long as no of lines does not increase, keep looping.
while(quotient<=globalHeight)
{
//Add tiny single blank space to the div's beginning
$('#mydiv').html(' '+myContent);
//Get the new height of line and height of div and get the new no of lines and loop again.
height = $('#mydiv').outerHeight();
lineheight = $('#mydiv').css('line-height');
quotient = parseInt(height)/parseInt(lineheight);
myContent = $('#mydiv').html();
}
//get the final div content after exiting the loop.
var myString = $('#mydiv').html();
//This is to remove the extra space, which will put the last chars to a new line.
var newString = myString.substr(1);
$('#mydiv').html(newString);
});
If you already know where you want your breaks to take place just use simple HTML breaks to break your content and have it display the way you want.
<p>This is what<br/>
want to acheive with your help</p>
If you set the breaks manually (and you know where you want them to break) then create them yourself.
You could also try setting separate css width adjustments based on the dimensions of the screen you are seeing the breaking you are not liking and set an #media reference to make the div width smaller to break the text so it doesn't run unevenly across the top of certain size devices.
Use display: inline-block; on the text div.

How to fix bottom of layout of 100% height (jQuery Mobile and Google Map)?

I have a layout where I would like the main content area to be 100% height of the remaining space. So I am almost there but the bottom is truncated (which effects zoom and centering). There is 41px from the bottom that is being truncated, which is the measurement of the header area: http://jsfiddle.net/GTscW/
The reason why I know if it cut off is because I do not see the Google map copyright info. Here is the not truncated, but truncates the top (I just removed the top: 41px from #content .inner-content): http://jsfiddle.net/GTscW/1/
How do I subtract 41px from the bottom from the first sample to get the content 100% of the remaining area?
EDIT:
I was able to add just this: $('#content .inner-content').height($(this).height() - $('#header').height()), but really no CSS solution though???
One issue is that it's not easy to mix percentages and pixel measurements, because different screen sizes will behave differently. But it is possible to use API features to get the map to behave the way you want it to, on any size screen.
Make the map 100% of the screen size, so the header obscures part of the map. Suppress the default map controls so they do not appear partially obscured. Create an empty custom control the same size as the header and position it at the top of the map. When the map controls are added back, the custom control pushes them out of their usual place so they look right on the visible map.
var posn=google.maps.ControlPosition; // shorten the reference
// Add empty custom control
var controlDiv = document.createElement('div');
controlDiv.style.width='100%';
controlDiv.style.height='41px';
map.controls[posn.TOP_LEFT].push(controlDiv);
map.controls[posn.TOP_RIGHT].push(controlDiv);
// Add map controls
map.setOptions({
mapTypeControlOptions:{position:posn.RIGHT_TOP},
mapTypeControl:true,
panControlOptions:{position:posn.LEFT_TOP},
panControl:true,
streetViewControlOptions:{position:posn.LEFT_TOP},
streetViewControl:true,
zoomControlOptions:{position:posn.LEFT_TOP},
zoomControl:true
})
http://jsfiddle.net/GTscW/4/
Note 1: Because the map is actually 41px larger than it looks (in your case), the centre-point will be 20px higher than the centre of the viewable map. This may not be worth worrying about. If it is, then dealing with an apparent centre-point is the subject of another question on SO.
Note 2: This method won't work to get a fixed footer, because the Google logo and Terms links are always at the bottom of the map and [currently] don't move to avoid a control.
I edited your fiddle with a solution: http://jsfiddle.net/T2Nkk/
Basically, create a function that looks something like this:
function remainder() {
$("*[height=\"remainder\"]").each(function(index, element) {
var offsetParent;
var target = $(element);
if (element==$("body")[0]) {
offsetParent = $("html");
}
else {
offsetParent = target.offsetParent();
}
var position = target.position();
var heightParent = offsetParent.height();
var extras = target.outerHeight(true)-target.height();
var remainderHeight = heightParent-position.top;
target.height(remainderHeight-extras);
});
}
For the element that you want to occupy the remainder of the page, do this:
<div id="content" data-role="content" height="remainder">
Finally, when your document is ready:
$(document).ready(function() {
remainder();
});
In css only you can try to use a trick : use both top and bottom attributes on position: absolute property like I did on your fiddle : http://jsfiddle.net/GTscW/23/
Don't know if it works everywhere though.

CSS: overflow-y: scroll; overflow-x: visible

See the following post for a picture highlighting my question and a potential solution:
CSS overflow-y:visible, overflow-x:scroll
However, this strategy breaks when you actually move the scrollbar. In the suggested implementation (position: fixed;), the tooltips display next to child div in its position pre-scroll. So, as you scroll new child-divs into view, the tooltips begin falling off the bottom of the page.
See here for a demo of the bug: http://jsfiddle.net/narcV/4/
Any ideas how I can make the tooltips display next to the child div at all times?
I ended up implementing this using javascript, using the getPos function from this question.
The end product looks like:
var scrollPanel = ...;
var tooltip = ...;
function nodeHovered(e) {
var hovered = e.srcElement;
var pos = getPos(hovered);
pos.x += hovered.offsetWidth;
pos.y -= scrollPanel.scrollTop;
tooltip.style.setProperty('left', pos.x);
tooltip.style.setProperty('top', pos.y);
}
Basically, I calculate where on the page the node is currently displayed (taking into account the scrollbar position), and manually place the tooltip in the right spot on the page.
Too bad there's no elegant/CSS way to do this, but at least this works.

Get div to adjust height with header content

I have a side bar that contains two divs. The first div may or may not have content, depending on what else is done on the page. The second div contains a long list of things and has a limited height, so scrolling is possible. I want to have the sidebar be as tall as the page, and I want the list container in the sidebar to be as tall as the sidebar minus the height of the header (which will change while using the page). I don't care about limiting the size of the header. The biggest is will get isn't anything significant.
Right now I'm just setting the height of the list container to be some number that is won't go over a maximized window height if the header div as as much content as it can, but this leaves an empty space at the bottom when the header is empty, and still doesn't work very well if the window is resized.
The layout is similar to this.
Is there a css solution to what I'm looking for, or will I have to use javascript and get window height/set div heights in pixels? I'm fine with either, it just seemed like there should be a CSS way to accomplish it.
If you're not opposed to using a little jQuery, here's a little code snippet that should help you equalize the height of the two divs, no matter which has more content. You can change it to your liking too.
var leftHeight = $(".left").height();
var rightHeight = $(".right").height();
var maxHeight = 0;
var div = "";
if (leftHeight >= rightHeight)
{
maxHeight = leftHeight;
div = ".right";
}
else
{
maxHeight = rightHeight;
div = ".left";
}
$(div).each(function(){
if ($(this).height() > maxHeight) { maxHeight = $(this).height(); }
});
$(div).height(maxHeight);
and credit where credit is due, this is an edit of a code snipped found at css-tricks.com
is this what you want?
http://jsfiddle.net/YWNyr/
CSS tips:
If you use 'absolute' positioning, width,height,left,top, etc... is relative to the first ancestor that has a "position" property other than "static", or the body if nothing is there.
for static menus, it is common to use 'position:fixed' as it will simplify scrolling issues
When using jquery its easier(and faster) to toggle a class than to change the DOM since that requires redrawing of the elements by the browser
-edit: for refreshing the sidebar size some javascript is necessary:
$('#headerAdd , #headerRemove').click( function()
{$('#sideContainer').height($(window).height()-$("#header").height());
} );
Try setting the height of your list container to 100%, and your overflow to scroll:
#listContainer {
height: 100%;
overflow: scroll;
}
This will keep the list in a scrollpane that reaches to the bottom of the page, no matter how large the header grows or shrinks.

Resources