I'm trying to get a layout in HTML/CSS done. The goal is about this:
Some elements in this layout have a non-fixed size. The area on the left has fixed width, the footer has fixed (content matching) height. The list on the left shall be extending it's height, the text in the footer it's width and the canvas both dimensions so the entire browser page is filled, but without causing any scrollbars to appear. Oh, and B is for button, but that's not really of importance I guess.
I have seen some examples (this) and references (this) and tried to learn from them, but I can't get it the way I want. One of the closer attempts I have made is this one:
<html><body style="margin: 0; padding: 0;">
<div style="position: absolute; background: #afa; top: 0px; bottom: 0px; left: 0; right: 0px;">
<div style="position: absolute; background: #afa; top: 0px; bottom: 0px; left: 0; width: 240px;">
<input style="width: 240px" id="selectedPosition"></input>
<select style="position: relative; width: 240px; height: 100%;" id="points" multiple="multiple"></select>
<div style="position: relative; background: #afa; left: 0; width: 240px;">
<input style="width: 80px" type="button" value="Add"></input><!--
--><input style="width: 80px" type="button" value="Up"></input><!--
--><input style="width: 80px" type="button" value="Down"></input>
</div>
</div>
<div>
<div><input style="position: absolute; bottom: 0px; left: 0px; width: 100%"></input></div>
<div><input style="position: absolute; bottom: 0px; right: 0px;" type="button" value="Button 4"></input></div>
</div>
<div style="position: absolute; background: #aaf; height: 100%; left: 240px;top: 0px;right: 0px; overflow: auto;"></div>
</div>
</body></html>
Problem here is the lower elements ant the button in the bottom right are covered by size extending elements. I probably could fix this with fixed dimensions or margins, but I'd like to have it done in a "proper" way.
Another approach was to use a 4x5 table with spanning rows and columns, but I got confused even more and quickly let that drop.
I'm fairly new to layouting in HTML/CSS, so any source "for dummies" in this matter helping me getting the job done in spite of an actual solution is appreciated also.
Update
After looking at the links and at Fico's answer. However, the closest attempt is this. Problem is that both the list and the bottom text overlap the respective button(s) when width/height is set to 100% (in the jsfiddle example I used lower numbers for demonstration purposes). As a side note, the list in the example given does not extend vertically at all. When using my local file, then it does.
All examples I have seen with a fixed footer and height filling columns use some fixed size height for the footer which is then negatively applied as margin, but my footer should just wrap it's content. Isn't there any way to set up a rule "extend until you reach the next element"?
Start by using markup for content and css for styling.
You will work cleaner and with less trouble.
It's not a good practice to include so many tags instead of using an external CSS (or eventually embedded in the HEAD of the document)
It doesn't seem to me, you are in the need of so much absolute positioning here.
Identify your big areas in your design (as the figure below)
First impression is that you got an aside column at the left width some elements in Normal document flow and in its bottom three buttons floating in a div
The canvas could be floating left or right of this aside
Both , the aside and the canvas , contained in a mainContainer div.
The text and button at the bottom could be integrated in a footer with the button floating right or left at your will
The flexible solution is simple to instrument. Use some min with properties for your canvas and probably some fixed widths for the aside.
Related
I have a fixed DIV that I have that sits at the top of a page and as the user scrolls down the page the fixed DIV moves down. When the user clicks on the fixed DIV it toggles and allows the user to upload an image.
The problem I have found is that if I have as an example a Google Map (DIV) underneath this shines through the Fixed DIV.
Example of DIV Fixed
<div id="flip" style="position: fixed; width: 98%;">CLICK TO ADD PHOTOS<br /><span style="font-size: 11px;">Expands to allow for uploading photo</span></div>
<div id="panel" style="position: fixed; margin-top: 35px;width: 98%; z-index: 100;"><iframe src="upload.aspx?id=<%Response.Write(Request.QueryString["id"]); %>&type=<%Response.Write (Request.QueryString["type"]); %>" style="overflow: scroll;height: 500px; border: 0px;" scrolling="no"></iframe></div>
How do I stop any DIV underneath this fixed DIV from displaying on the top of the fixed DIV?
Sounds like changing the CSS z-index property would fix your problem.
#flip { z-index: 100; }
#panel { z-index: 50; }
add z-index: 101; to your div with I'd flip to position it on top of the other div.
<div id="flip" style="position: fixed; width: 98%; z-index: 101;">CLICK TO ADD PHOTOS<br /><span style="font-size: 11px;">Expands to allow for uploading photo</span></div>
<div id="panel" style="position: fixed; margin-top: 35px;width: 98%; z-index: 100;"><iframe src="upload.aspx?id=<%Response.Write(Request.QueryString["id"]); %>&type=<%Response.Write (Request.QueryString["type"]); %>" style="overflow: scroll;height: 500px; border: 0px;" scrolling="no"></iframe></div>
set the z-index of your divs always higher for the ones you want underneath them. if the div you describe with the Google maps in it has a z-index of let's say 1000, set your other elements higher than 1000 in order to be on top of the ones set with a lower number.
A. z-index could get to a really high number in certain situations. Up to 2147483647 (90000 would be enough). Try changing the element you want above everything to a very high number to discard this is the issue.
B. Switch (Invert) the order between both divs.
As you didn't provided the rest of the HTML this are two easy to test solutions.
z-index CSS property would solve your problem, a div with the highest value for z-index property would always show in the top, so you need to add a z-index value for flip div higher than 100 (panel's z-index value)
<div id="flip" style="position: fixed; width: 98%; z-index: 101;">CLICK TO ADD PHOTOS<br /><span style="font-size: 11px;">Expands to allow for uploading photo</span></div>
<div id="panel" style="position: fixed; margin-top: 35px;width: 98%; z-index: 100;"><iframe src="upload.aspx?id=<%Response.Write(Request.QueryString["id"]); %>&type=<%Response.Write (Request.QueryString["type"]); %>" style="overflow: scroll;height: 500px; border: 0px;" scrolling="no"></iframe></div>
Refer to this for more information about z-index CSS property.
I have div, which position is set to absolute. Also I have couple paragraphs inside of it. When I move right side of explorer to the left, the paragraphs move with it and try to adjust to size of window. I tried to position them absolutely, but them still move. How can I set that div or paragraphs inside it, so they remain on the same spot? Please... Here is the code:
HTML:
<div id="search_slogan" > <!-- search_slogan Slogan-->
<p style="font-size: 26px; "> Free Business Name Search </p>
<p style="font-family:gothic; "> Enter any potential business name.
We'll let you know if the company name is available for use in your state, </p>
<p style="font-family:gothic; "> usually within 1 business day. </p>
</div> <!-- END search_slogan Slogan-->
CSS:
#search_slogan{
line-height: 15%;
position: absolute;
top: 150px;
left: 200px;
font-family:basic_gothic;
font-size: 18px;
}
Your problem might be that your box has no set width, so it fills the space remaining.
Add a set width like below and it won't move anymore.
#search_slogan{
line-height: 15%;
position: absolute;
top: 150px;
left: 200px;
width: 400px;
font-family:basic_gothic;
font-size: 18px;
}
There are additional solutions with things like hiding the overflow, but setting the width is the simplest.
The problem was your line:height property, that was set to 15%. That will cause letters to pile up. I cleanen up your HTML and created a JSFIDDLE HERE.
Sorry for the messy code:
<div style="position: relative;">
<div style="position: absolute; top: 50%;">This should be vertically centered</div>
<img src="http://phaseoneimageprofessor.files.wordpress.com/2013/07/iqpw29_main_image_.jpg" width="100%" style="visibility: hidden; position: absolute;"; />
<img src="http://phaseoneimageprofessor.files.wordpress.com/2013/07/iqpw29_main_image_.jpg" width="100%" />
</div>
http://jsfiddle.net/a5as2/
as you can see, the text is almost centered vertically - but as you will shrink the width, you will see thats not 100% precise. What to fix now<
A pure css solution would be to set the inside div a height, and add margin: -height/2 px for it.
Example:
<div style="position: absolute; top: 50%; height: 20px; margin-top: -10px;">This should be vertically centered</div>
In case you don't know the height of the div, you can use js to get it, then reposition the div.
Will be something like (jQuery, directly in answer so might have some problems, adapt it pls.):
$("#idDiv").css("margin-top") = parseInt($("#idDiv").height() / 2) + "px";
Another solution, would be to use table-cell display, and vertical-align: middle (I personally don't like it, but may fit your needs).
What about this?
http://jsfiddle.net/a5as2/3/
.use-a-stylesheet-and-classes-please { top: 50%; position: absolute; }
It is in the middle, even if you shrink it.
You can position the elements when shrinked by using media queries. And... please, don't use inline styling.
Here is a simplification of my layout:
<div style="position: relative; width:600px;">
<p>Content of unknown length, but quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite long</p>
<div>Content of unknown height</div>
<div class="btn" style="position: absolute; right: 0; bottom: 0; width: 200px; height: 100px;background-color: red;"></div>
</div>
The problem I'm having is that if the text/unknown div content is too long it is overlapping my absolutely positioned div.
I have searched the web and SO for a solution and the only one I found suggested putting an invisible div where absolutely positioned div is - trouble is if I could do that I wouldn't need to have the absolutely positioned div in the first place (or am I missing the point here).
Can anyone think of a css solution before I go down the jquery route?
The solution for me was to create a second invisible div at the end of the content of unknown length, this invisible div is the same size as my absolutely positioned div, this ensures that there is always a space at the end of my content for the absolutely positioned div.
This answer was previously provided here:
Prevent absolutely-positioned elements from overlapping with text
However I didn't see (until now) how to apply it to a bottom right positioned div.
New structure is as follows:
<div id="outer" style="position: relative; width:450px; background-color:yellow;">
<p>Content of unknown length</p>
<div>Content of unknown height </div>
<div id="spacer" style="width: 200px; height: 25px; margin-right:0px;"></div>
<div style="position: absolute; right: 0; bottom: 0px; width: 200px; height: 20px; background-color:red;">bottom right</div>
</div>
This seems to solve the issue.
Short answer: There's no way to do it using CSS only.
Long(er) answer: Why? Because when you do position: absolute;, that takes your element out of the document's regular flow, so there's no way for the text to have any positional-relationship with it, unfortunately.
One of the possible alternatives is to float: right; your div, but if that doesn't achieve what you want, you'll have to use JavaScript/jQuery, or just come up with a better layout.
If you are working with elements of unknown size, and you want to use position: absolute on them or their siblings, you're inevitably going to have to deal with overlap. By setting absolute position you're removing the element from the document flow, but the behaviour you want is that your element should be be pushed around by its siblings so as not to overlap...ie it should flow! You're seeking two totally contradictory things.
You should rethink your layout.
Perhaps what you want is that the .btn element should be absolutely positioned with respect to one of its preceding siblings, rather than against their common parent? In that case, you should set position: relative on the element you'd like to position the button against, and then make the button a child of that element. Now you can use absolute positioning and control overlap.
Put a z-indez of -1 on your absolute (or relative) positioned element.
This will pull it out of the stacking context. (I think.) Read more wonderful things about "stacking contexts" here: https://philipwalton.com/articles/what-no-one-told-you-about-z-index/
Thing which works for me is to use padding-bottom on the sibling just before the absolutely-positioned child. Like in your case, it will be like this:
<div style="position: relative; width:600px;">
<p>Content of unknown length, but quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite long</p>
<div style="padding-bottom: 100px;">Content of unknown height</div>
<div class="btn" style="position: absolute; right: 0; bottom: 0; width: 200px; height: 100px;background-color: red;"></div>
</div>
<div style="position: relative; width:600px;">
<p>Content of unknown length</p>
<div>Content of unknown height</div>
<div id="spacer" style="width: 200px; height: 100px; float:left; display:inline-block"></div>
<div class="btn" style="position: absolute; right: 0; bottom: 0; width: 200px; height: 100px;"></div>
</div>
This should be a comment but I don't have enough reputation yet. The solution works, but visual studio code told me the following putting it into a css sheet:
inline-block is ignored due to the float. If 'float' has a value other than 'none', the box is floated and 'display' is treated as 'block'
So I did it like this
.spacer {
float: left;
height: 20px;
width: 200px;
}
And it works just as well.
Could you add z-index style to the two sections so that the one you want appears on top?
You should set z-index to absolutely positioned div that is greater than to relative div.
Something like that
<div style="position: relative; width:600px; z-index: 10;">
<p>Content of unknown length</p>
<div>Content of unknown height</div>
<div class="btn" style="position: absolute; right: 0; bottom: 0; width: 200px; height: 100px; z-index: 20;"></div>
</div>
z-index sets layers positioning in depth of page.
Or you may use floating to show all text of unkown length. But in this case you could not absolutely position your div
<div style="position: relative; width:600px;">
<div class="btn" style="float: right; width: 200px; height: 100px;"></div>
<p>Content of unknown length Content of unknown length Content of unknown length Content of unknown length Content of unknown length Content of unknown length Content of unknown length Content of unknown length</p>
<div>Content of unknown height</div>
<div class="btn" style="position: absolute; right: 0; bottom: 0; width: 200px; height: 100px;"></div>
</div>
I'm responding because I also ended up in this post and found a simple and effective solution: the absolute element has a fixed position and size, so you simply need to add right padding of 400px (referring to your example) to your content
put texts into a new div. Then make that div also position: absolute; . Also, you can use overflow: hidden; for that div.
I have been trying to get this right for days but I just can't.
My scenario is this: I need three columns of equal height. There needs to be borders between them. The left column will have a bit more content than the other two and the other two need to have buttons at the bottom (that are positioned so that their bottom edge is where the left column's content ends).
Here is an image that shows what I mean: http://img217.imageshack.us/img217/6400/49593032.png
I have tried the huge-padding-bottom-and-equally-huge-but-negative-margin-bottom-hack which works great until I try to move the buttons down. At first I tried to use absolute positioning on the button and position:relative on the container but since the container needs overflow: hidden to work the button will be hidden and placed at the bottom of the container (which is about 32767 pixels down due to the huge padding).
I also tried using the above hack while adding a second row which I put the buttons in. Besides the fact that the semantics of that don't make much sense, this method made it so that the content of the left column doesn't go all the way down. Since the hack required overflow: hidden attempts to use negative margins to push the second row up didn't work out either.
So I'm stuck here. Faux columns wouldn't help me and javascript is not an option. What would you do?
Use A List Apart's Holy Grail and position the buttons absolutely.
Don't really like it in this case, but at least one solution would be to use a table. The text height in the first column would force the height for the other cells, and you could use relative positioning inside the cells (with a div) to have the buttons at the bottom.
[removed code --- not 100% sure about your exact requirements]
You can use absolute positioning for your divs and then absolute position the buttons in them. Try this code:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
body { height: 100%; margin: 0; }
.col {
width: 33%;
position: absolute;
top: 0;
bottom: 0;
border: 1px solid #000;
background: blue;
position: absolute;
}
.left { left: 0; }
.mid { left: 33.33%; }
.right { left: 66.66%; }
.button { position: absolute; bottom: 0; right: 0; }
</style>
</head>
<body>
<div class="col left">
sdgfiods ajgodsai jngfio nmsadogf nikod sangf sfdsg fdsg
</div>
<div class="col mid">
sdgfiods ajgodsai jngfio nmsadogf nikod sangf sfdsg fdsg
<button class="button">click me</button>
</div>
<div class="col right">
sdgfiods ajgodsai jngfio nmsadogf nikod sangf sfdsg fdsg
<button class="button">click me</button>
</div>
</body>
</html>