Floated image to left of a ul is ignoring margin/padding - css

I have a paragraph followed by an unordered list, with several list items. I also have an image floated to the left of that. The problem I am having is that the list item margin/padding is being overlapped by that image.
I want the bullets that are next to the image to indent like it should.
Here is a test I wrote up for debugging, where you can see my issue in action.
All of this is inside of a CMS, so the image dimensions are variable, as well as the paragraphs and possible lists in the text.
Any solutions?
(See my first comment for pictures.)

ul {
overflow: auto;
}
I'll have the added advantage of not having the list items wrapping around the image.

Add this:
ul{ list-style-position: inside}
That's it!

Another option would be to shift the list to the right with relative positioning:
img+p+ul {
position: relative;
left: 1em;
top: 0;
}

li style="margin-left: 135px;" Worked best for me.
The overflow: auto; looked ok up front but wound up messing with other elements in my HTML.

You can give your list items an overflow property:
li {
overflow: hidden;
}
That will cause the list item to sort of behave correctly: They will display as a square block, continuing where the image ends as well, they donĀ“t flow nicely to the left. The next list item will.

If you don't bother about adding javascript, here is a jQuery script that will add a margin to the ul that overlaps the image so all the list items remain aligned, and then assigns a negative margin to the li's that doesn't overlap.
$(function(){
//Define a context so we only move lists inside a specified parent
var context = $("#test_div");
//Build a list of images position a size
var imgRects = [];
var imgs = $("img.left", context);
imgs.each(function(i){
var pos = $(this).position();
pos.right = pos.left + $(this).outerWidth(true);
pos.bottom = pos.top + $(this).outerHeight(true);
imgRects.push(pos);
});
//Process each li to see if it is at the same height of an image
var lis = $("li", context);
lis.each(function(i){
var li = $(this);
if(li.parent().css('marginLeft') != "0px"){
return; //Already moved
}
var top = li.position().top;
for(var j in imgRects){
var rect = imgRects[j];
if(top > rect.top && top < rect.bottom){
li.parent().css('marginLeft', rect.right);
return;
} else if(li.parent().css('marginLeft') != "0px"){
li.css('marginLeft', -1 * rect.right);
}
}
});
});
I've tested with your demo page and jQuery 1.3.2 and it works on FF3.5 and IE8 because the image is on top of the document. If the image appears in the middle of a ul, the firsts li's will remain padded. If you need to correct this issue leave a comment and will try to update the script.

Related

CSS positioning with JavaScript-generated divs not working how I expected

First off, I must apologize. CSS positioning has always been the bane of my existence and this is likely something simple that I'm just completely missing...
Anyway, I have a JS script that's generating divs. Each div is within the parent #container which is absolute positioned. CSS below:
#container{
position: absolute;
}
#container div{
position: relative;
}
The function creating the divs is:
function newLine(){
var id_num = ++line;
var _new;
var i;
for(i = 0; i < width; i++){
_new = document.createElement('div');
_new.innerHTML = randomChar();
_new.id = id_num;
_new.style.left = i*10+'px';
_new.style.top = 0;
document.getElementById('container').appendChild(_new);
}
}
Everything above is properly initialized. The left positioning works perfectly. The only issue is the vertical positioning. Instead of all the row displaying next to each other, they're progressively increasing away from the top of the div. I'm sure this is something trivial that I'm completely looking over, but I'm stumped... Help would be very much appreciated!
The rows as position: relative - this lays them out statically and then moves them the specified number of pixels. You want to use absolute positioning.

DIV float with page

How can I get a DIV to float with my page? Currently I have it setup like this: http://g2n.us/Dev/TheHabbos_6975/
I can do this by using the following CSS:
Code:
.stayStill {
position: fixed;
width: 300px;
}
But how can I get it so when the header scrolls away, the right DIV moves up and stays 10 pixels away from the top and scrolls with the page, unless the header is there?
You need JavaScript to do this.
Your site is already using it, so there should be no problem with using JavaScript to do this.
A couple of tutorials:
http://jqueryfordesigners.com/fixed-floating-elements/
http://css-tricks.com/scrollfollow-sidebar/
This answer uses jQuery
You can put this in your $.ready() function
var int_header_height = 10; //put pixel value height of header here
if ($(document).scrollTop() <= int_header_height) {
$('div.stayStill').css('position','absolute').css('top','0px');
} else {
$('div.stayStill').css('position','fixed').css('top','10px');
}
This also assumes that the div is in a position: relative element below the header. Otherwise you should change the .css('top','0px') to .css('top',int_header_height + 'px')

Get height of dynamically changed height div

How can I determine (using jQuery?) the height of a div? Its' height is not defined in CSS - so it's fluid and based on the contents.
I've tried $('#div').height() - which returns 0.
Ideas?
EDIT: (the code)
$(document).ready(function () {
PositionBottomPicture();
});
function PositionBottomPicture() {
var parentOffset = $('#left_pane').offset();
var parentsHeight = $('#left_pane').height();
var childsTopPostion = (parentOffset.top + parentsHeight);
$('#bottom_pic').offset({ top: childsTopPostion, left: parentOffset.left });
}
CSS:
#left_pane
{
float: left;
margin-left: 27px;
position: relative;
}
where 'left_pane' and 'bottom_pic' are divs.
Thanks!
The problem is you're probably not waiting for the div to load into the DOM.
Try something along the lines of:
$(document).ready(function(){
var h = $("#div").height();
var w = $("#div").width();
;})
Using the Document Ready tool provided by jQuery will wait till the element has been processed.
If 'left_pane' only contains absolutely positioned elements it's height will be zero.

how to fill div with full height of page in css? (page is taller than 100%) for ajax loading gif background

ok there are several similar questions but not quite anything that I want.
I have few ajax requests on page and I want to show the image in the center of the screen, and its all working OK.
Just to make it look more prominent, I wanted to place that image on a div with translucent background, so its more obvious for the end users. Now comes the tricky part.
I made the div with css like this:
.divLoadingBackground
{
filter: Alpha(Opacity=40); -moz-opacity:0.4; opacity: 0.4;
width: 100%;
height: 100%;
background-color: #333;
position: fixed;
top: 0px;
left: 0px;
}
This fills the page up alright, or, I should say, this fills the viewport. If I scroll the page down, the page is again normal. I want this div to span the ENTIRE LENGTH of the page, no matter how long the page is.
Here is an example mockup of the problem I made to quickly demonstrate:
As you can see, I took the example of SO for the mockup ;) image 1 shows that its okay when it appears. image 2 shows that it goes up with the page on scroll.
I'm a c# developer and css is as alien to me as ancient latin.
How to make this divLoadingBackground div to fill out the entire length of the page?
Many thanks for any help.
If you need any additional info, please comment!
One thing I dont see in your css is z-index. Fixed, although, fixes this problem, sometimes, based on how other divs are positioned, your divLoadingBackground div could end up in one of the divs.
try adding
z-index: 9999;
or something similar and see if it works.
Would have put this in a comment, but it seems I have too low rep to comment.
Where is the .divLoadingBackground div located in the DOM tree? Since it has fixed position, it shouldn't scroll with the page. This makes me belive that the element is too deeply nested. Try putting it right in the body level of the page and see if that helps.
Also, are you sure that some other css directive isn't changing the position attribute to absolute or something?
Also, make sure to use the right DOCTYPE. That has some impact on fixed position elements.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
Oh, and ofcourse, fixed position isn't supported in IE6 and below.
I believe you will need JavaScript/jQuery to dynamically set the height of the div in question to the height of the page once rendered.
And if you're entering the world of web, it's time to learn that new language "CSS" as well as perpahs-not-quite-as-daunting JavaScript.
When I needed such a functionality some years ago, I examined how Google Calendar did it.
Basically, they use a timer-driven JavaScript file that checks for the height of the window and adjust the height of a contained DIV tag accordingly (or of an IFRAME tag, just any container tag that you like).
Here is a code snippet from a page I worked on:
<script type="text/javascript">
document.getElementsByTagName("body")[0].style.height = "100%";
document.getElementsByTagName("html")[0].style.height = "100%";
document.getElementsByTagName("body")[0].style.minHeight = "100%";
document.getElementsByTagName("html")[0].style.minHeight = "100%";
function height()
{
try
{
height_iframe();
}
catch(err)
{
}
}
window.onload=height;
// --
var ie6WorkaroundIFrameResize = 1;
function height_iframe()
{
var any = false;
var offset = 300;
var c = document.getElementById("iframecontent");
if ( c!=null )
{
c.style.height = (GetClientHeight()-offset)+"px";
any = true;
var d = document.getElementById("iframeie6");
if ( d!=null )
{
d.style.height = (GetClientHeight()-(offset+ie6WorkaroundIFrameResize))+"px";
any = true;
ie6WorkaroundIFrameResize = 0;
}
}
if ( any )
{
setTimeout( 'height_iframe()', 300 );
}
}
function GetClientHeight()
{
return document.documentElement.clientHeight;
}
</script>
Basically, the script regularly checks for the height of the window via the GetClientHeight() function and adjusts the element in concern ("iframecontent") accordingly.
I subtract some offsets of fixed-height headers and footers.
AFAIK you would need to set the size of this divthrough javascript. I would recommend using jQuery, in this way :
//$(document).height() gives the size of the document
//(as opposed to $(window).height() that would give the size of the viewport
$("div#overlay").css('height',$(document).height());

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

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/

Resources