Best technique to center an element using position relative/absolute? - css

I'm trying to get consistent centering cross browser when I set the position property of the parent element to relative and the position of the child to absolute (the child is the element I'm trying to center)
Currently in firefox it's not exactly center, but ie6/7 it is (sample of what i'm using below)
#wrapper { min-width:995px; position: relative; }
#wrapper2 { margin:0 auto; z-index: 0; position: absolute; }

Are you trying to horizontall center, vertically center or both?
In either case use of margin and absolute is incompatible. Position absolute takes it out of the normal flow. If you take out the position absolute the inner div is horizontally centered correctly.
Whatever you want to do, centering (especially vertical centering) is a huge problem in pure CSS, particularly if IE6 support is required.
If you must use absolute positioning on the inner div, you pretty much need to rely on pixel positioning, which means knowing the fixed sizes of the outer and inner divs (barring a few corner cases).

If you're interested in a jQuery approach, I used the following a few weeks ago:
$(window).load(function() {
$("ul.recent-list div img").each(function() {
var moveX = ($(this).width() / 2 * -1) + 18;
var moveY = ($(this).height() / 2) * -1 - 18; // 18 is 1/2 the default offset of 36px defined in CSS
$(this).css({'top' : moveY, 'left' : moveX});
});
});
I had to take an image of an unknown size and position it within a "window" of 36x36px so that only the 36 square px area of the image was visible through the window <div>.
The (window).load was needed instead of (document).ready because Safari cannot use the width() and height() functions if no width/height attributes are defined on the image on document.ready. Since my images were of varying dimensions, I had to use window.load instead.

Related

How to place elements on top of each other

I have a <button> with 3 spans in it - each span containing different text. At different times, triggered by Javascript, the class of the button will change. Using CSS transitions & transform, I have one span moving out of the button, and another moving in. That all works.
The problem is that the button has grown to the full width of span 1 + span 2 + span 3. I want the width to be simply large enough to contain the largest of the spans. If all the spans could be placed one on top of the other, this would work.
I can't figure out how to get the 3 spans to sit one on top of the other.
Here's a fiddle showing the problem: http://jsfiddle.net/V9yTs/ (Click the button to see the change)
Edit Here's the final, working fiddle: http://jsfiddle.net/XW3DY/7/
A solution for layering your spans on top of each other would be to use position: relative; (which I see you already have there) and then modify the top margin of spans 2 and 3 so that they move up to the same position as the span 1.
Here's an updated version of your JSFiddle: http://jsfiddle.net/XW3DY/2/
(Please note that floated elements cannot be placed on top of each other. This is why relative positioning is generally used for placing elements of top of one another.)
Since you already use jQuery, you can just calculate the proper width and height
var w = 0;
$('.btn .msg').each(function () {
w = Math.max(w, $(this).width());
});
$('.btn').width(w);
var h = 0;
$('.btn .msg').each(function () {
h = Math.max(h, $(this).height());
});
$('.btn').height(h);
But now the .msg spans are arranged vertically. To compensate for that, depends on what you what to achieve. One solution is to use position: absolute
.btn {
position: relative;
}
.btn-status .msg {
position: absolute;
}
The .msg spans are now lying on top of each other. You must also adjust the vertical transformation.
See modified JSFiddle

Div Height/Overflow issue

The problem I'm having is I have two divs at the top of my page, one contains a repeating blue background, the other contains a background image.
I have to set the height of both divs in order for them to expand vertically, the don't expand with the content. I have that form on the right hand side set to overflow. Which I believe is what's causing the problem.
I have tried not having the height css in the code, but it still won't expand vertically.
In order to get the backgrounds to even show up I have to manually set the height.
This is the page: http://www.repipespecialists.com/landing/google/repiping.html
This is the CSS code:
#top_container {
width:100%;
height:1040px;
background-image:url(../images/top_bg_repeat.jpg);
background-repeat:repeat-x;
background-color:#83b4e9;
}
#top_header {
width:1200px;
height:1040px;
background-image:url(../images/header_bg.jpg);
background-repeat:no-repeat;
background-color:#83b4e9;
margin: 0 auto;
}
I agree with WDan in that the issue you are having is due to your use of float: left and float: right on the left_content and right_content div elements.
When you use float on an element, you are basically removing it from the normal flow of the document. By default, elements will appear on the page in whatever order you specify in the markup. Using float (or things like position: absolute) will remove the element from this "order", or "document flow", such that the floated element will be ignored when placing other elements in their default position on the page.
Since the space used by these floated elements are ignored, the top_header div does not take the floated element's size into account when determining its own size. This is why your div is not automatically expanding.
Another alternative to float is to use display: inline-block. Here are some links you can read to learn more about the differences:
http://www.ternstyle.us/blog/float-vs-inline-block
http://www.onderhond.com/blog/work/inline-block-vs-float/
http://designshack.net/articles/css/whats-the-deal-with-display-inline-block/
http://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/
I think the problem is you use float in 'left_content' and 'right_content'
Use “overflow: hidden” in the wrapper div.

Vertically center element and switch to align top if height is too small

I have been trying to find an answer to this, but all I have found are only discussing centering an element vertically.
What I am trying to do is center a div vertically, which I know how to do with css. The problem is if the height is too small it will still center it and cut off top and bottom.
Here is a demo of what I mean: http://jsfiddle.net/reitermarkus/23B43/
Fullscreen demo: http://fiddle.jshell.net/reitermarkus/23B43/show/light/
Can you tell me how to align it to top if the height is too small? Preferably without JS.
Thank you,
Markus
The only way you could possibly determine whether the height is below the minimum required is through JS:
var el = document.getElementById('id');
var el_height = el.offsetHeight;
if(el_height < min_height){
//apply class or inline style
el.className = 'align_top';
}
Obviously you'll need to define the min_height var. Furthermore for DOM manipulation it would be better to use jQuery. Aligning the element to the top of the document would just be a case of removing the negative margin and defining 'top' as 0;

Make a div nested in a jQuery UI dialog resize with the dialog?

My jQuery UI dialog contains two div elements. One has a fixed height and should be aligned at the bottom of the dialog at all times. The other one should take up the remaining space.
Basically I’d like all the dimensions highlighted in blue to remain unchanged on resize. Or, in other words, the red div resizes in both dimensions but the green div keeps its height.
What’s the easiest way to do this in jQuery UI or even just plain CSS?
I’ve found a way to do this that doesn’t use any JavaScript. It doesn’t even involve any hacks; just plain normal CSS3. Fiddle here: http://jsfiddle.net/nty5K/16/
Basically, both divs are position: absolute, and each of the sides is anchored individually using the top, bottom, left and right properties. The top div has all four positions specified, making it resize with the container while preserving the exact distance to each edge of the container. The bottom div has three of the positions fixed, whereas the top is defined only indirectly, via a fixed height.
In practice, the divs will need to be placed into a wrapper div that has position: relative, otherwise the top/bottom divs will be positioned relative to the body element.
Not sure about browser compatibility yet, but this worked fine in Firefox 10, IE9 and Chrome 17. Didn’t test this in earlier versions.
Corporate firewall is blocking images, so I am guessing what you are after based on other comments.
EDIT:
Now that I can see what you are after, I have updated my fiddle accordingly. Including the code below for completeness.
I would write a function to calculate the size of the dialog, subtract the height of the fixed div and set the height of the dynamic div to this calculated value. I would then bind a call to this function to the resize event of the dialog. Here is a fiddle, may need some tweaking for your exact layout but should be close.
One gotcha worth noting is that some browsers may not calculate correctly while they are in the middle of a scroll/resize event, queing the calculations to occur after the resize event completes with setTimeout resolves the issues, though it does make the change a bit jumpy while the resize is in progress. See this question and answer for details.
function SetDivHeight() {
var $DynamicDiv = $('div.dynamic');
var $FixedDiv = $('div.fixed');
var $Container = $(window); //Update for containing element
/*Calculate the adjustment needed to account for the margin and
border of the dynamic div.*/
var HeightAdjustment = $DynamicDiv.outerHeight(true) - $DynamicDiv.height();
/*Get the values of the top and bottom margins which overlap
between the two divs.*/
var DynamicBottomMargin = parseInt($DynamicDiv.css('marginBottom'));
var FixedTopMargin = parseInt($FixedDiv.css('marginTop'));
/*Adjust for the overlapping top/bottom margin by subtracting
which ever is smaller from the adjustment value.*/
if (DynamicBottomMargin >= FixedTopMargin) {
HeightAdjustment -= FixedTopMargin;
} else {
HeightAdjustment -= DynamicBottomMargin;
}
/*subtract the height of the fixed div from the height of the
container, subtract the calculated height adjustment from that
value, and set the result as the height of the dynamic div.*/
$DynamicDiv.height(($Container.height() - $FixedDiv.outerHeight(true)) -
HeightAdjustment);
/*May need to use $Container.innerHeight instead, if container
is not a window element.*/
}
var t;
function QueueSetDivHeight() {
if (t) {
clearTimeout(t);
}
t = setTimeout(function() {
SetDivHeight();
}, 0);
}
$(document).ready(function() {
SetDivHeight();
$(window).resize(QueueSetDivHeight);
//Bind to resize of container element instead/as well
});
Just CSS... check it out!
Set a margin to the container and a margin-top to the bottom fixed div. No jQuery required.

variable height scrolling div, positioned relative to variable height sibling

recently i asked this question: overflow (scroll) - 100% container height about how to achieve a vertically scrolling div with variable height.
a very helpful user provided a solution using absolute positioning and height:100%, here: http://jsfiddle.net/TUwej/2/. in this fiddle, you can see the basic desired behavior - the scrolling div will fill the height of the main container as is determined by the content in the '#main' element.
i modified this somewhat and used top:0 bottom:0 instead of height:100% to accommodate an element above the scrollable area. the modified version can be seen here: http://jsfiddle.net/N6muv/3/ (i realize there is a little extra markup and class definitions that are empty, and an adjacent sibling combinator that appears redundant - these are vestiges of the actual structure)
everything is fine, except that i had to supply a fixed top coordinate for the scrolling div (note the top:120px declaration for the '.sidebar-list' selector). i'd like this to be relative to the '.sidebar-options' element above it, so that the options container above can have any number of options and the scrollable div will position itself appropriately. using fixed coordinates, if any options are added or removed, either overlap occurs or unnecessary space develops - i'd like to avoid this. the exact number of options that should appear varies between views.
i had thought to wrap the scrolling div in a relatively positioned container, but doing that creates a conflict with bottom:0 no longer indicating the height of the main '.wrapper' container (which it should do). similarly, using height:100% will use the computed height of the '.wrapper' container so the scrollable div will extend beyond the boundary of the '.wrapper'.
is there a way to keep the functionality shown in the second fiddle, but with the top of the scrollable div relative to the bottom of the options div (which will be of variable height)?
thanks in advance for any suggestions.
EDIT: S.O. asked if i wanted to start a bounty, so i did (first time) - hopefully 100 pts isn't considered too low. still looking for a no-script, pure-css solution that doesn't involve fixed coordinates or dimensions for the y-axis (width and left assignments are OK). thx
UPDATE:
Import JQuery:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
New Demo:
http://jsfiddle.net/Mutant_Tractor/N6muv/28/
Add this nice little JQuery script to your page:
var contentColHeight = $('.content').height();
var optionColHeight = $('.sidebar-options').height();
var newHeight = contentColHeight - optionColHeight;
$('.sidebar-list').height(newHeight);
OLD
How does this suit your needs?
http://jsfiddle.net/Mutant_Tractor/N6muv/4/
I changed position:absolute; to position:relative and added a static height:190px as well as adding background:pink; (so the bg always looks right)
You can try adding and removing Options from the list above to demo this.
Full code:
.sidebar-content {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background : pink;
}
I believe you should remove absolute positioning on the inner elements and try overflow:auto.
You need to define the height of the sidebar list coz you have to set this content to scroll-able and min or max height must be defined. And you could set .sidebar-list{position: relative;} See this Fiddle
Edit Your .sidebar-content should also be relatively positioned See this Fiddle whatever your 'options' content contains.

Resources