Alignment with fixed elements and scrollable content - javascript

Here is a simplified JSFiddle of the problem.
As you can see, the content is beat out of alingment with the header because of the scrollbar.
As far as I know, the only way to deal with this is to calculate the width of the scrollbar using Javascript (David Walsh's excellent method springs to mind) and to set it as left/right: -scrollbarwidthpx value to the header.
However, considering the dynamic nature of the page I'm working on, with the headers place in the DOM and position changing depending on at what point the user has scrolled to, this is an option I am hoping to turn to only if there's nothing else I can do.
My question is, is there any way that I can maybe take the scrollbars or the content out of the flow while preserving a scrolling overflow, or otherwise align the two elements using only HTML/CSS? Are scrollbar widths consistent across all browsers/OS's that have them affect the flow? Or will I have to resort to using Javascript to align them?
Thanks!

html, body {
width: 100%;
height: 100%;
overflow: hidden;
margin: 0;
}
.scroll {
overflow: auto;
width: 100%;
height: 100%;
}
#content{
width: 400px;
height:auto;
margin: auto;
background:gray;
}
.header {
width: 400px;
position: fixed;
margin: 0 auto;
height: 60px;
background: yellow;
z-index: 10;
}
.content {
height: 1200px;
background: linear-gradient(red, orange);
width: 100%;
margin: auto;
position: relative;
z-index: 1;
border-top:61px solid;
border-bottom:1px solid;
}
<div class="scroll">
<div id="content">
<div class="header"></div>
<div class="content"></div>
</div>
</div>

Related

Fixed aspect ratio box with letter and pillarboxing between header and footer

Running the following code snippet will provide a framework for what I am visually hoping to accomplish, with some concessions made in the CSS that I'd like to remove:
body {
height: 100vh;
margin: 0;
}
.container>* {
height: 100%;
width: 100%;
flex: 0 0 50px;
}
.container {
width: 100%;
height: 100%;
background-color: black;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.header {
background-color: red;
}
.content {
background-color: blue;
flex: 1;
position: relative;
}
.footer {
margin-top: auto;
background-color: yellow;
}
.fixedRatio {
height: 56.25vw;
max-height: calc(100vh - 100px);
width: calc((100vh - 100px) * (1/0.5625));
;
max-width: 100vw;
background-color: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
<div class="container">
<div class="header"></div>
<div class="content">
<div class="fixedRatio"></div>
</div>
<div class="footer"></div>
</div>
Included are a header and footer of arbitrary height and a fixed aspect ratio box centered vertically and horizontally between them. I'd like it to letter- and pillar-box as the page is resized, and respond to increases/decreases in header height.
As it stands, the code accomplishes many of these goals but falls short in that it requires that the heights of the header and footer be included in the CSS for the fixed aspect ratio box. This limits my ability to freely manipulate the size of the header, or let it grow arbitrarily as a function of content (at least to the extent I am not using JavaScript).
I've managed to make this work successfully for the case of letter-boxing (top and bottom black bars) by leveraging the fact that the content is full-width. As a result, I can use 100vw / 56.25vw (in the case of 16:9) for the width/height and achieve the desired result. Unfortunately, when moving the content around to pillar-box, this obviously falls apart.
I've more or less resigned myself to needing JavaScript to - at the very least - toggle a class based on the dimensions of the inner content box to determine whether letter or pillar boxing is appropriate. However, it became very clear very quickly that setting width as a function of height is not trivial.
I was fortunate to come across this post, where a solution leveraging a 1x1 pixel is used to set width as a function of height.
I was able to successfully make this work for the pillar-boxing case in both Chrome and Safari, but not Firefox (IE11 and Edge not yet tested, but coverage is desired... pray for me). I'd like to get recent versions of Chrome/Safari/Firefox covered, as well as I11/Edge if possible.
The solution for Chrome/Safari is as follows:
body {
height: 100vh;
margin: 0;
}
.header,
.footer {
height: 100%;
width: 100%;
}
.container>* {
flex: 0 0 50px;
}
.container {
width: 100%;
height: 100%;
background-color: black;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.header {
background-color: red;
}
img {
display: block;
height: 100%;
background: orange;
}
.content {
background-color: blue;
flex: 1;
position: relative;
overflow: hidden;
height: 100%;
display: inline-block;
left: 50%;
transform: translateX(-50%);
}
.footer {
margin-top: auto;
background-color: yellow;
}
.fixedRatio {
background-color: purple;
position: absolute;
left: 0;
top: 0;
right: 0;
margin: auto;
bottom: 0;
}
<div class="container">
<div class="header"></div>
<div class="content">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" />
<div class="fixedRatio"></div>
</div>
<div class="footer"></div>
</div>
There are a few things to consider. I am comfortable with fixing the height of the footer. This constraint may prove valuable, but I've been unable to yield anything from it yet. I am also comfortable with radical alterations to the included markup, supposing it enables the desired behavior.
The end-purpose of this would be to maintain fixed aspect ratio content between this flexible header, static footer, and overlay content upon it.
I am well aware that I could run some JavaScript and set these heights manually with great success, but I am coming at this from a position largely based in intellectual curiosity. If you, too, are curious, perhaps you can lend a hand in exploring :)
Thank you!

align texts or images in Bootstrap carousel

I use Bootstrap 3.3.4 and I want to know which way is better to align texts or items in carousel.
here is a exemple from a slider. How can I align text like this and stay at any screen resolution at the same place. I use top: x, right: x but every time when I resize the window, text climb above and not stay at middle anymore.
CSS for align
.carousel-caption {
position: absolute;
right: 15%;
bottom: 40%;
left: 15%;
z-index: 10;
padding-top: 20px;
padding-bottom: 20px;
color: #fff;
text-align: center;
text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
}
Just basic bootstrap slider. But If I use bottom 40% for exemple to rise text at middle of the page works. But if I use smaller displays the text rise and stay almost on top.
In this exemple text stay fixed on every device.
<div class="wrap">
<div class="display-table">
<div class="display-cell">
<h1>Title in here</h1>
</div>
</div>
</div>
<style>
.wrap {
width: 100%;
height: 400px;
}
.display-table {
width: 100%;
height: 100%;
display: table;
}
.display-cell {
width: 100%;
height: 100%;
display: table-cell;
vertical-align: middle;
}
</style>
This allows fixed vertical alignment and should work cross browser. Just note the fixed height applied to .wrap must be present for the children to inherit 100% height!
Hope this helps :)
Hope, Try this demo that centers text vertically in the Bootstrap carousel.
Here is the Fiddle.
All I do here is give the div a height that contains the text and then position it with this css...
.vcenter {
position: absolute;
height:100px;
width:100%;
top:50%;
bottom:50%;
margin-top: -50px;
margin-bottom: -50px;
}

How to align a website to the center of the screen top/bottom and right/left?

I want to have the effect like dropbox:https://www.dropbox.com/ where my website is centered in the exact middle of the page.
Achieving this effect is way more complicated than it should be. Here's a bare-bones working example: http://jsfiddle.net/JakobJingleheimer/UEsYM/
html, body { height: 100%; } // needed for vertical centre
html { width: 100%; } // needed for horizontal centre
body {
display: table; // needed for vertical centre
margin: 0 auto; // needed for horizontal centre
width: 50%; // needed for horizontal centre
}
.main-container {
background-color: #eee;
display: table-cell; // needed for vertical centre
height: 100%; // needed for vertical centre
// overflow: auto; // <- probably a good idea
vertical-align: middle; // needed for vertical centre
width: 100%; // needed for horizontal centre
}
.container {
background-color: #ccc;
padding: 20px;
}
If you want to achieve this:
Here are different methods, with the pros/cons of each one, for centering a page vertically. Choose which one you prefer:
http://blog.themeforest.net/tutorials/vertical-centering-with-css/
EDIT. As suggested, I will proceed to explain one of the methods. It only works if you already know the height/width of the element to center (the link includes more methods). Assuming all your content is within <body>, and that your content is 900px x 600px, you can do in your css:
html {
width: 100%;
height: 100%;
}
body {
width: 900px;
height: 600px;
position: absolute;
top: 50%;
margin-top: -300px; /* Half of the height of your body */
}
However, this falls short for dynamically generated content, since you don't know the height of it. I've used it succesfully on log-in box pop-up and settings pop-up.
Another method I've used in the past for the whole page is the Method 1 from the link. It makes a set of divs to behave as a table, which can vertical-align to the middle.
If you want to align it vertically center, please check this web page: http://www.jakpsatweb.cz/css/css-vertical-center-solution.html
If you know the width and height of your page
then wrap your contents in following div css
.center
{
position:absolute;
top:50%;
left:50%;
margin-left: -(yourPageWidth/2);
margin-top: -(YourPageHeight/2);
}
On your topmost div give margin:0 auto 0 auto; Also define some width to that div.
First create a main container of the desired width and then put all your code inside the main container. For Eg.
<body>
<div id="container">
......... your code
</div>
</body>
And in the css
#container{
width: 700px ;
margin-left: auto ;
margin-right: auto ;
}
You can change the width as per your needs
<body>
<div class="container">
......... your code
</div>
</body>
#container{
width: 700px ;
margin:0 auto ;
padding:0px;
}
Try this:
html
<span id="forceValign"></span><!--
--><div id="centerMiddleWrap">
<div id="centered">Hello this is some text. Hello this is some text. Hello this is some text.</div>
</div>
CSS
html {
height: 100%;
background: #eee;
}
body {
margin: 0;
height: 100%;
/*important*/
text-align: center;
}
#centerMiddleWrap {
/*important*/
display: inline-block;
vertical-align: middle;
}
#forceValign {
/*important*/
height: 100%;
display: inline-block;
vertical-align: middle;
}
#centered {
background: #000;
color: #fff;
font-size: 34px;
padding: 15px;
max-width: 50%;
/*important*/
display: inline-block;
}
Here is an demo
Wrap a div and define its width, use margin:0 auto for centering the div.
You can check a site's CSS by using Firebug or browser extensions.

Can I use `overflow: scroll` on a div with variable height?

Is it possible to use overflow: scroll on a div that has height set to auto?
I have a div with an unordered list inside of it. The amount of items in the list is variable so there is no way I can use a fixed height. The div that contains the unordered list is where the scrollbars need to be, here is my code:
#page {
height: auto; /* default */
overflow-y: scroll;
overflow-x: hidden;
}
As stated, the unordered list is contained within the #page div. The height of the page is assigned by the unordered list's value. Is there a way to make overflow: scroll work on a div with variable height like this or must I use JavaScript to do this?
Thanks
One way of approaching this design...
Suppose that you have the following HTML:
<div class="main">
<div class="inner">
<ul>
<li>Some list items...</li>
...
</ul>
</div>
</div>
The .main block is fitted to the page, for example, by absolute positioning:
.main {
border: 2px dashed blue;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
The .inner block holds the navigation list that can cause scrolling:
.inner {
border: 2px dotted red;
position: absolute;
top: 10px;
bottom: 10px;
left: 10px;
right: 10px;
overflow-y: scroll;
}
In this example, I constrain the height of the .inner block to fit within .main,
and set overflow-y: scroll, which creates a scroll bar contained within the edges
of the container block.
You may have to adapt this to your mobile platform, but the concept should still apply.
Demo fiddle: http://jsfiddle.net/audetwebdesign/ac4xT/
Simply put, if it has variable height (auto), it will never have overflow in the y axis (vertically), because the div will always grow to fit its contents.
overflow: scroll will force it to present a scrollbar, but it will always be disabled, because the contents will never extend beyond the displayed pane.
If you want vertical scrolling, you have to define a height, either in px, %, or em.
If you do height: 100%, the div will fill the height of the page, and scroll content that extends beyond the window's viewport height.
If you have a header area, try something like this:
body {
margin: 0;
}
#header {
position: absolute;
width: 100%;
height: 40%;
background-color: #ccc;
}
#body {
position: absolute;
top: 40%;
width: 100%;
height: 60%;
overflow-y: auto;
background-color: #eee;
}
<body>
<div id="header">
<p>Header</p>
</div>
<div id="body">
<p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p>
<p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p>
</div>
</body>
For a fixed-height header (per the comments), use absolute positioning with a top and botom value to position the scrollable div below it:
body {
margin: 0;
}
#header {
position: absolute;
width: 100%;
height: 60px;
background-color: #ccc;
}
#body {
position: absolute;
top: 60px;
bottom: 0px;
width: 100%;
overflow-y: auto;
background-color: #eee;
}
<body>
<div id="header">
<p>Header</p>
</div>
<div id="body">
<p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p>
<p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p>
</div>
</body>
Why not use max-height on the div?
max-height sets the maximum height to which an element can expand. I suppose what you want is the div to never go out of the screen. So you can set a max-height and then overflow: auto;

Fixed positioning overlap issue

I am in a corner with this one. I have a layout with 2 containers. One of the containers represents a map (#main) and needs to stay in user view at all times, the other one (#sub) serves as a scroll-able content. Everything looks fine if content fits horizontally. However as soon as the horizontal bar appears (resize the window to replicate), the scroll-able content overlaps the fixed content and I am out of ideas how to fix it. I know of one way to fix it by positioning the fixed content absolutely instead and useing javascript to adjust its position from the top. Is there any way to fix it?
Sample code is below:
Html:
<div id="content">
<div id="main">main</div>
<div id="sub">
<strong>Sub</strong><br />
sub<br />
sub<br />
sub
</div>
</div>
Css:
#content {
width: 1200px;
margin: 0 auto;
}
#main {
position: fixed;
width: 849px;
height: 500px;
background: red;
}
#sub {
position: relative;
float: right;
width: 350px;
height: 3500px;
background: green;
}
JSFiddle link
Based on your comments it sounds like not allowing the user to scroll will solve the issue:
body {
padding: 0;
margin: 0;
overflow-x:hidden;
}
If you want them both to scroll you have to remove the fixed positioning:
#main {
position: relative;
width: 849px;
height: 300px;
background: red;
font-size: 50px;
text-align: center;
padding-top: 200px;
float:left;
}

Categories