I've written a web-app for an in-house resource for my fellow employees, and part of the base template is a simple dialog box - a hidden div, between the body and the header with an absolute position that appears when a button (another div) is clicked, displays content based on the clicked button, and goes away when the X in the corner is clicked. You know the routine.
So I suspect that I should not have to do this, but I find that I have not yet been able to describe the CSS of the dialog box in the base template's CSS such that I can ensure its position on the screen is always more or less the same. It seems instead that, as the dimensions of the content of the dialog box change per page, this requires that I redefine the dialog box's margin-left and margin-right on any given page.
For example, my base css for the dialog box is such, and it is loaded with the base html template every time:
#dialogBox {
position: absolute;
border: 4px solid;
border-radius: 15px;
cursor: default;
text-align:center;
z-index:1000; /*always on top*/
padding: 10px 0 10px 0;
font-size: 36px;
}
Note the lack of a margin - I've not found a single margin value that does the job without causing a vicious mismatch of the size of the dialog box to the content within. For example, on a page where the content is expected to be quite large, I've set the margin as such:
#dialogBox {
margin: 5% 10% 0 10%;
}
If the content is expected to be much lighter, however, it seems that the margin needs to be set again on the next page I load, in order to circumnavigate visual shenanigans:
#dialogBox {
margin: 5% 33% 0 33%;
}
This is Not A Big Deal, but it is repetitive. I'm certain there's a better way to do it, such that the div will just naturally expand and maintain equal margin-left and margin-right on any given page its on, while maintaining a 'Goldilocks' size for its content - not too big, not too small, always just right.
I realize that there is existing infrastructure within some of the jQuery libraries for 'nice-looking' dialog boxes - they even drag around the screen and do tricks - but this is just for an in-house, employees-only web-app so I just haven't any interest in that. Also, it's good to know how to build some things yourself, right? I'm a little too new at this to cheat and just steal a bunch of CSS, so I'm trying to come by the knowledge honestly.
If I've left out any code which is germane to the issue, I'm more than happy to edit my post.
EDIT - I have two excellent answers regarding placing the dialogBox in a containing div - and the only reason I haven't flatly accepted them is just because it looks like I may end up needing to redefine aspects of the dimensions on each page in spite of some one-and-done code. Which is probably my fault, because the information on different pages is a little too different, and I would like to avoid forcing my users to scroll the page if necessary. Setting the width of the dialogBox per-page lets me do that; I dunno if leaving it up to CSS will let me do that.
FINAL EDIT - I believe for now that the accepted answer is the best solution for my project.
I'm not sure you can solve this without adding another container. With a wrapper you can make that position: absolute; instead and then center inside it, without the need for negative margins etc.
html
<div class="container">
<div id="dialogBox">content of whatever size here</div>
</div>
css
.container {
height: 0; /* hide/ make unclickable if necessary */
left: 0; right: 0; /* full width */
text-align: center; /* center inline content */
position: absolute;
}
#dialogBox {
/* make div stretch to its content and allow centering */
display: inline-block;
/* reset the inherited text-align */
text-align: left;
}
This way you don't need to care about the width of the dialog box.
Demo at http://jsfiddle.net/9wcFb/
Alternatively, you can also use margin: auto; when the container is the absolutely positioned one. http://jsfiddle.net/9wcFb/1/
Sidenote: as this #dialogBox is likely depending on JavaScript anyway, if you don't like the extra markup it is entirely possible to add it using the script, although I'd argue that would be a case of over-engineering ;)
Is setting a width on the dialog box an option?
If it is, you can set the left property to 50% and the margin-left property to -(width/2)
See here:
http://jsfiddle.net/tY7ef/
#dialogBox {
position: absolute;
border: 4px solid;
border-radius: 15px;
cursor: default;
text-align:center;
z-index:1000;
/*always on top*/
padding: 10px 0 10px 0;
font-size: 36px;
left: 50%;
margin-left: -200px;
width: 400px;
}
You can use percentages too:
width: 60%;
margin-left: -30%;
auto margins won't typically work with absolute positioned elements: http://www.sitepoint.com/css-center-position-absolute-div/
You can try using an auto margin, this way the div's should be centerd automaticly
#dialogBox {
margin: 5% auto 0;
}
I can think of two quick methods to do this depending on whether or not you know the width of the element
If you know the width
If you know the width of your div, set the distance from the left side of the screen and subtract half of the width in a margin.
Say your screen is this wide:
/*
Legend:
Edge of screen: |
Center of element: .
Beginning of div: [
End of div: ]
*/
| . |
| .{center} |{size:56 characters}
And you have a div of this width:
[---I am .a div---]{size:16 characters}
In order to center it using this method, we would set the distance from the left side to half of the screen (left: 50%;):
| .[---I am .a div---] |
| . |
And then subtract the extra distance in the margin, 50% of the total size of the div or, in our case 8 characters. (margin-left:-8 characters;):
| [---I am .a div---] |
| . |
We now have a centered div.
This will work with any width-type you use (px, %, em...) as long as you move the div back to the left exactly half of its width.
#dialogBox{
width:70%;
left:50%;
margin-left:-35%; /*half of 70%*/
}
#dialogBox{
width:100px;
left:50%;
margin-left:-50px; /*half of 100px*/
}
#dialogBox{
width:202em;
left:50%;
margin-left:-101em; /*you get the picture*/
}
Fiddle
If you don't know the width.
Make a new div which will act as a container for your dialogue box. Set the left: value of this container div (position:absolute;) to 50% and subtract 50% from the left: value of your dialogue div (now position:relative;).
We have a div within a div:
[[---I am .a div---]]{size:still 16 characters}
/*
It is important to note that the width of the outer div
will always be equal to the width of the inner div
unless defined otherwise.
*/
If we set our container div (C) to be 50% from the left of the screen (left: 50%) then we get:
CD DC
| .[[---I am .a div---]] |
| . |
Now, we set the left of our dialogue box div (D) to -50% (subtracting 50% of the width of the parent element which in this case is exactly 50% of the width of the dialogue box.)) and get:
D C D C
| [---I am .[a div---] ] |
| . |
This effectively centers the dialogue box without knowing its width.
#container{
position: absolute;
left:50%;
}
#dialogBox{
position: relative;
left:-50%;
}
Fiddle
I made the container div red in the example so that you can see how it is working.
Related
Code: https://jsfiddle.net/gsnfzn35/3/
It's a bit funky to describe, click the toggle drawer button. A pull out drawer on the right shows up. That pull out drawer is one container, but has 2 key components. The first component is all the content at the top. The last component is a "fixed row" on the bottom:
<div class="scroll-fixed-row" style="width:100%;text-align: right">
<p>
FIXED FINAL ROW
</p>
</div>
This row SHOULD be the width of the pull out drawer, whatever that width is; NOT the width of the screen. Currently though, if you inspect element with the width:100%, you see that the width is the width of the screen, not the pull out drawer. Another way to see this is in the fact that when there's width:100%;text-align:right, the text is off screen, pulled to the right of the row that is too wide. Remove the width:100% and you can see the text again.
I'm guessing this is due to the fact that the scroll-fixed-row is fixed, and therefore, its taking width from the screen, not the pull out drawer itself. But this fixed is necessary, because that scroll-fixed-row needs to stay at the bottom even though the rest of the pull out drawer scrolls. Given that constraint, how can I set the width of the scroll-fixed-row to be the width of the pull out drawer, for any screen (full responsiveness) WITHOUT having to provide specific width in pixels based on media queries?
The reason I'm asking this is because I would like to divide the scroll-fixed-row into 2 "sections" using either a table and 2 <td width="50%"> or using Bootstrap grid and 2 <div class="col-xs-6"> in a row. In the current implementation (NOT in the Fiddle), the content in the 2nd grid just gets pushed off page (same issue now) because the table width is inheriting from the screen. I think I can figure that part out if someone can help me answer this question.
The width can be solved by using inherit instead of 100%, this will make a fixed element get the width of its parent, in your case .container.scroll. I noticed that you have padding added to parent, the inherited width will include paddings and so the fixed element will overlay the scrollbars.
Code:
.scroll-fixed-row {
position: fixed;
text-align: right;
background-color: white;
border-top: 1px solid black;
width: inherit; /* get width from parent */
bottom: 0; /* stick to bottom */
right: 0; /* fix offset caused by padding */
}
Another thing I noticed that in your code is that you are using margin-top: 70px on .scroll to offset it from the fixed red nav, this causes the the bottom part that is out of viewport to be invisible, especially the bottom scroll arrow. I've changed it to the following:
.scroll {
position: fixed;
top: 70px; /* offset from top (nav height) */
height: calc(100% - 70px); /* calculate height minus the top offset */
}
If you wanted to prevent the fixed element from overlapping the scrollbars, you could apply pointer-events: none and add another wrapper in the HTML that gets a 15px spacing like the content, for better consistency:
.scroll-fixed-row {
...
pointer-events:none; /* disables mouse functionality to enable scrollbar control */
}
.scroll-fixed-row .inner {
border-top:2px solid red;
background:lightblue;
margin:0 30px 0 15px;
pointer-events:auto; /* allows mouse functionality */
}
jsFiddle demo - scrollbar overlap: https://jsfiddle.net/azizn/guufj4a0/
jsFiddle demo - additional wrapper: https://jsfiddle.net/azizn/d6wwk51b/
I have a table on my webpage, that uses a specific print CSS, that removes all the web site elements so that it can be printed on posters.
What I do is:
Visit the page with Google Chrome,
Click: File -> Print -> "Print using system dialog...",
Click PDF -> "Save as PostScript", and
Process with Adobe Distiller (150 dpi & 18” x 24”).
Since I want my table to fill the 18"x24" (18/24 = 3/4) poster nicely, how can I make sure that its width/height aspect ration is 3/4, without putting in specific dimensions that would come to bite me in print?
For now, the only solution that came to my head is the one where you'd have to wrap the table with two additional divs.
Here's the fiddle
As we speak, I'm trying to improve the solution to get rid of the divs.
At the moment I'm using one div as a wrapper with width set to 100%, then inside of it there is another div (innerWrapper) which is positioned absolutely and spread to the wrapper's dimensions. To set the div's height I used a simple trick - added a pseudo :after element to the wrapper which has padding-bottom set to 133%. Padding percentage values are inherited from parent's width (yes!). In case of somebody asking - we can't ommit the innerWrapper div and set its style directly to table becuase top, right, bottom, left method won't work for it (neither width and height set to 100%). Divs are block elements, tables have display: table.
Whole code looks like this:
HTML:
<div id="wrapper">
<div id="innerWrapper">
<table></table>
</div>
</div>
CSS:
#wrapper {
width:100%;
position: relative;
}
#wrapper:after {
content: "";
display: block;
padding-bottom: 133%;
}
#innerWrapper {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
table {
width: 100%;
height: 100%;
}
At cjshayward.com/index_new.html, there is a wrapper div around the body's content, about 1000 pixels wide, and it works as intended for the top 100 or so pixels in Chrome and Firefox. Next down the page is a jQuery UI set of tabs, containing a fixed-width accordion and something close to jQuery.load()ed plain old, simple HTML.
However, on the "Browse the Library" tab (but not "About the Author"), which is presently open and which contains the fixed-width accordion, below 100 or 150px down, the area under the tabs appears to have the same width as the window; it has the correct left margin, and horizontally scrolls an apparently equal distance to the right. Furthermore, the body background tile does not display; the whole width is white, as was specified for the wrapper div's interior.
How can I get the "Browse the Library" tab to display as intended (like the "About the Author" tab does)?
Thanks,
You're absolutely positioning way too much and that's ruining the flow of things. I'll go through a list of edits you can do to make this work.
/*
#accordion and #details will be floated, so we'll need to
clear #tabs. Add this property.
*/
#tabs {
overflow: hidden;
}
/*
Remove the absolute positioning from #accordion, along
with the top and left properties and do this instead.
*/
#accordion {
float: left;
width: 400px; /* This already exists */
margin: 0 10px 0 0;
}
/*
Remove the absolute positioning from #details, along
with the top and left properties and do this instead.
*/
#details {
float: left;
width: 580px;
}
This will get you a lot closer. You should also try to avoid using height on these elements. Let the content dictate the height.
Here is what i ended up with making those edits: http://i.imgur.com/niizuoR.png
Okay lets make a step by step solution (watch for the edits).
Background
Your background is set in the body. So the body needs to be extended to fill the whole page.
I would recommend this way but there are others.
body,html{
height:100%;
}
Normally the body would fit its contents but with position:absolute this mechanism doesnt work anymore.
Also remove background: #fff css (normalize.css) from the html.
html {
background: #fff;
color: #000;
font-size: 100%;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
Also your background scrolls with your content. Set background-atachment: fixed to change this.
Wrapper
Same counts dor your wrapper which holds the white background.
Set its height to 100% too.
div#main {
height: 100%;
}
The reason why your content is bigger than your wrapper is that
<div id="details" style="width: 713px; height: 0px;">
this div holding the content has a fixed size set. Removing that size make it fit the wrapper.
The width seems to be set per javascript in the load event, so I cant help you with that. Provide your .js code and may i can help you with that too.
As stated in the comments, your layout issues are based in your use of absolute positioning rather than flow layout:
I went through your site and quickly switch everything so it was positioned statically (width floats, not absolute values) and this cleared up the issue. There were some other issues as well. You probably need to look over how you are setting up your HTML from the top level on.
I would start out again and concentrate on using floats for your layout, rather than absolute positioning.
For a basic example on doing so, here is a super simply page: http://cdpn.io/kmCFy
I'm writing a mobile/desktop chat application that is supposed to utilize the entire screen. The bottom <div> shown in yellow can be fixed-height if it needs to be.
presently it's Absolutely positioned to the bottom of the window.
My problem: the top <div>, in cyan, doesn't fit to the rest of the window, regardless of whether I use padding, margin, border, etc. Presently it appears to allow the content to wrap, but that's only because the bottom overwrites the scroll bar.
My only solution so far is to have a final <div> or <br> that pads the end of the scrollable div, but that doesn't make the div smaller, or make the scroll bars properly align.
Here is my source code so far in Fiddle.
Can you edit your CSS and set the DIV with the chat text a class like .break-word and then in CSS declare it with word-wrap:
.break-word {
word-wrap: break-word;
}
Unsure on the covering of scrollbars. You should post your code for others to view and might be able to pick something out.
This style code basically sums up what I'm doing to compensate for my issue. (Instead of, say, using HTML tables.) This may not be the best solution.
#topPart {
position: absolute;
width: 100%;
top: 0;
bottom: 40px; /* or however high the bottom is */
}
#bottomPart {
position: absolute;
width: 100%;
bottom: 0;
height: 40px; /* same as above */
}
I'd like to create a that extends from wherever it starts to the bottom of the page, but does not extend beyond the bottom of the page. It has overflow-y: auto, so that if the div content is too long, a scroll-bar will appear (for that only, not for the whole page).
I tried height:100%, but that makes the height equal the page height... so if the doesn't start at the very top of the page, it ends up being too tall.
(Example: window height is 100px; stuff at the top of the page take 20px; I want the to be 80px high. But I want it to be automatically resized to 70px if the window is resized to 90px.)
Can this be done without JS? If not, how do I use JS to do that? (Using FF 3.x, but a cross-browser solution is of course preferred.)
Sounds like you want something along the lines of the following:
#myContainer {
position: absolute;
top: 20px;
bottom: 0px;
left: 0px; /* Should include space for a sidebar, if you have one. */
right: 0px; /* Same as above */
}
OK, found the solution -- making the position absolute and setting the bottom to 0 (and top to whatever the top is).
Have you tried setting the body margin's to 0?