CSS for dual divs scrolling independently of each other - html

I have a page with 2 divs, inside a single container div.
I would like to use the left hand side div as a menu, containing various links or text, and to scroll up and down (vertically) by itself.
The second div, shows some content. Usually a table of data, but it could be text too. This div must be able to scroll both horizontally and vertically according to content.
I have some javascript that populates the content for both, but for simplicities sake, I will only show my css and html:
-------------------
| | |
| 1 | 2 |
| | |
| | |
-------------------
The issue I have is in IE (I am running IE9), the second div drops off the view, and goes into a second row, instead of being aligned within the the container div. This layout and css works fine in chrome and firefox.
Any ideas on how to make this consistent within IE9?

IE9 does not support flexbox, so IE9 is doing what it should, according to its own limited knowledge: it's treating #browser-view as a block-level element without a width set, so it's dropping it to the second row.
You'll need to specify a fixed width on #browser-view like you did with #browser-list and also need to affect its display from its normal block default (you could float these divs, make them display: table-cell, etc. etc.).

Well, after a bit more research and some testing, I have decided to move away from flexbox in my CSS just so that I can support IE9.
Here is an updated cross-browser testbed, that appears to do what I want and works on all browsers so far.
*
{
margin: 0;
padding: 0;
}
html, body, .Container
{
height: 100%;
}
.Container:before
{
content: '';
height: 100%;
float: left;
position: relative;
z-index: 1;
}
.Container:after
{
content: '';
clear: both;
display: block;
}
.Container
{
position: absolute;
width: 100%;
height: 100%;
}
.Container > div
{
height: 100%;
}
.browser-view
{
background-color: purple;
overflow: auto;
}
.browser-list
{
background-color: orange;
float: left;
overflow: auto;
width: 250px;
}

Related

How do I set a center container to stay responsive?

I have three containers (div), the third div has a set width but I need the other two to be responsive. Current html setup:
<div id="page-type">
<div id="type-container">
<div>
<p id="type-title">Events</p>
</div>
</div>
<div class="type-options">
</div>
<div id="type-back">
Back to Explore
</div>
</div>
Current css:
#page-type {
float: left;
width: 100%;
background: #D2D3D5;
height: 60px;
}
#type-container {
float: left;
width: auto;
}
#type-options {
height: 60px;
width: auto;
overflow: hidden;
}
#type-back {
border-left: 1px #BDBEC1 solid;
float: right;
width: 160px;
}
I can get type-container and type-options to be on the same line and responsive but I can't keep type-back on the same line.
visual example:
----- EDIT -----
To clarify more:
type-container adjusts to fit it's content
type-back is a set width
type-option fills in the space between type-container and type-back regardless of content
type-containerand type-options fill up the whole row pushing type-back to the next line. I need type-back to stay to the right of the line while the other two are responsive.
Put a wrapper around your first two columns and then you can use CSS3's calc().
#wrapper {
width: calc(100% - 161px); /* extra px for 1px border */
float: left;
}
Demo here
IE8 Workaround - Use border-box:
#wrapper {
margin-right: -161px;
padding-right: 161px;
width: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
IE8 Demo
In CSS3 you can use calc(X% - 160px) to reduce the width of a percentage based container by a number of pixels.
A quick example could be: http://jsfiddle.net/e3vC4/
There isn't a need to use calc for this, even though its a nice feature to have (+1) — sadly its support is still patchy in places and despite much research it's still difficult to say exactly which browser versions will work as expected (fine if you assume all modern browser users auto-upgrade however).
Depending on what your prerequisites are, you have two other options that I'm aware of:
1. Position absolute the last column
This is a simple solution, however something to be wary of is that certain older mobile devices may treat position absolute in odd ways.
In order to get this to work, all you need to do is place position: relative on your container, and position: absolute; right: 0; top: 0; on your third column... and to keep the centering of your central column correct, add margin-right: 161px.
Pos. Abs. example on JSFiddle
CSS ~ markup is as per your example
#page-type {
display: block;
position: relative; /* added */
width: 100%;
background: #D2D3D5;
height: 60px;
overflow: hidden;
}
#type-container {
display: block;
float: left;
text-align: center;
}
#type-options {
display: block;
height: 100%;
text-align: center;
overflow: hidden;
margin-right: 161px; /* added */
}
#type-back {
display: block;
position: absolute; /* added */
right: 0; /* added */
top: 0; /* added */
border-left: 1px #BDBEC1 solid;
width: 160px;
height: 100%;
}
2. Float right, and/or left, before sibling without hasLayout / shrinkwrap
This works on the basis that a floated element takes up space in the document, and a block element, by default, auto-expands to fill the remaining area that it can — as long as it hasn't been forced to rigidly define its edges with the likes of float, overflow or other hasLayout or shrinkwrap tricks.
This option is only open to you if you can re-arrange your DOM ordering i.e. place #type-back before #type-options. This won't affect the visual order, but it makes a big difference to how the layout is calculated, and is one of the reasons why you were encountering problems with your attempts. You need to have the floated elements in place before leaving the other elements to calculate their dimensions.
Float example on JSFiddle
NOTE: Changing the order of DOM elements can be of benefit, but it can also be a hindrance; it all depends on what the markup is, and who will be viewing it. For example, sometimes having actionable links higher up the DOM can be useful to tabbing and screen-reader users, but the opposite can also be true depending on the context.
MARKUP ~ note the rearranged DOM order
<div id="page-type">
<div id="type-container">
<p id="type-title">Events</p>
</div>
<div id="type-back">
<p>Back to Explore</p>
</div>
<div id="type-options">
<p>Options</p>
</div>
</div>
CSS
#page-type {
display: block;
width: 100%;
background: #D2D3D5;
height: 60px;
overflow: hidden;
}
#type-container {
display: block;
float: left;
text-align: center;
}
#type-options {
display: block;
height: 100%;
text-align: center;
overflow: hidden;
}
#type-back {
float: right;
border-left: 1px #BDBEC1 solid;
width: 160px;
height: 100%;
}
NOTE: It should be stated this version does break on to the next line when "responsed" down to a very minimal size. However, I tend to prefer to design items to disappear when space is tight, and this method lends well to that thinking.
Summary
These are just two other possible options. If you are developing for a progressive client, or yourself, then I personally would stick with the calc method. It's easier to work out what is going on, and far easier for a future developer to change.
However, sometimes often frequently all the blasted time clients want to support the widest range of devices possible (without investing the extra time and money that would be required), and in this instance you are better off with an alternative method (one that isn't going to randomly break on a manager's less than contemporary laptop, running IE 7.5? or 8.33333??? or even Netscape 4.7¿).
Unless of course, you have any leeway to fight for using the more progressive approach, which does seem to be getting easier of late.
I sat down with the designer for more clarification and to discuss alternate solutions. I'm making the third did responsive as well allowing me to use two containers: one holds page-type and type-options set to x% and another holds type-back set to y%. Doing this allows me to keep all elements responsive.

Making inputs and selects fill remaining width

I am trying to setup a form such that:
All inputs will be horizontally aligned, even when they have no label.
Inputs will be vertically aligned within their row for when the label wraps.
The inputs will stretch to fill the remaining space (or squished)
The submit button will fill an entire row.
I have achieved the first and fourth requirements but I am having trouble with making the inputs fill the row and be vertically aligned.
Here's my progress so far:
http://jsbin.com/kozozabo/3/edit?html,css,output
The LESS:
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
#narrow-form {
width: 300px;
overflow: hidden;
padding-right: 0.5em;
}
#wide-form {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin-left: 300px;
}
.row {
#label-width: 100px;
width: 100%;
overflow: hidden;
label {
width: #label-width;
float: left;
display: inline-block;
}
.no-label {
margin-left: #label-width;
}
input, select {
/* Trying to make these aligned to the right of
* their respective labels filling any remaining
* width.
*/
display: inline-block;
}
button {
width: 100%;
}
}
I tried giving the inputs absolute positioning with a left margin of the same width of the label but that didn't work.
Okay I have come up with a solution that I am happy with. It does involve some table abuse unfortunately.
I have only tested this in Chromium.
http://jsbin.com/kozozabo/5/edit?output
I set the form to display: table, each .row to display: table-row and the labels, inputs, selects and buttons to display: table-cell.
This made everything line up and fill all available space.
I then added two new classes intended to be affixes to the .row class, this is where the real table abuse begins.
.no-label - With the intent of "skipping" the first psuedo-cell. To accomplish this I defined it as such:
.no-label:before {
content: "";
display: table-cell;
}
Essentially inserting a hidden cell, forcing the subsequent inputs to be in the second column.
.full-width - With the intent of making it's contents the full width of the "table". To accomplish this I defined it as such:
.full-width {
display: table-caption;
caption-side: bottom;
}
A table caption spans the entire width of the table. I know I am only going to do this to the button so I forced it to be at the bottom with caption-side.
It would have been better to just define the DOM as a table but I didn't want to reprogram the javascript that was setting up this form. I always wouldn't get to of played with css, all be it in a menacing manner.

Center multiple row list items with specific amount per row

I'm trying to create an unordered list spanning over multiple rows that is always centered and where I can set which child breaks into a second row, for example -
link | link | link | link
link | link | link | link | link
(where I set the list to clear for a second row on the fifth child element)
Going for an inline display solution to center the elements, I couldn't find a way of clearing them so I switched back to having a float based list. While this easily handles clearing, I find it difficult to center multiple rows -
.container {
width: 100%;
overflow: hidden;
}
ul {
list-style: none;
position: relative;
float: left;
display: block;
left: 50%;
}
li {
position: relative;
float: left;
display: block;
right: 50%;
}
li:nth-child(5) {
clear: left;
}
With this style, the list loses center alignment as soon as a second row is made.
Ideas?
Solved using inline approach and nth-child / after pseudo attributes - http://jsfiddle.net/2LULR/
To center multiple floats rows you have to center them manually. So I think the best solution is using display: inline and center them by setting the parent element to have a text-align: center.
And to clear or make a new row, I would do something like this:
li:nth-child(5):after {
content: "";
display: block;
}

CSS dynamic text alignment depending on the length of the text

Let say i would like to cover the below 2 scenario (the title is dynamic) :
Could that be achieved with CSS only (no JS) for IE8+ ?
Scenario A : short header title to be aligned center relatively to the page width
| back button | short Title |
<-----------------------------------|----------------------------------->
Scenario B : very long header title to fill the header content area without being overlayed on the back button
| | Very very very very very very very very very very very |
| back button | Very very very very very very very very long Title |
<-----------------------------------|----------------------------------->
Two ways I can think of:
Float the back button left, and the title will wrap naturally.
HTML
<div>
Back
<h1>Title</h1>
</div>
CSS
div {
text-align: center;
}
a.back {
float: left;
margin-right: 20px;
}
Or this way, same HTML - Just realised this wont center things properly, unless you have the same 100px padding on the right hand side as well.
div {
position: relative;
min-height: 30px;
padding-left: 100px;
text-align: center;
}
a.back {
position: absolute;
top: 50%; left: 0;
width: 90px;
height: 30px;
margin-top: -15px;
}
That second one will avoid any wrapping issues and also vertically align the button in the middle.
Hope that helps :)

How can I hide an element off the edge of the screen?

I've got a div that I want to position partially off-screen like so:
div {
position: absolute;
height: 100px;
width: 100px;
right: -50px;
top: 50px;
}
But this increases the size of the page, allowing it to be scrolled to the right. Is there any way to keep half of this div hidden and prevent scrolling to view it?
Yes, just create an enclosing div with overflow: hidden, like this:
.outer {
overflow: hidden;
position: relative;
}
.inner {
position: absolute;
height: 100px;
width: 100px;
right: -50px;
top: 50px;
}
<div class="outer">
<div class="inner">
CONTENT
</div>
</div>
Example: http://jsfiddle.net/Uj3eQ/
Just add overflow:hidden to the css. That should do the trick.
Just insert this div inside another div with overflow:hidden
You could add a media query to avoid scrolling at a certain point. So basically take the width of your main container and create a min-width media-query using that.
#media (min-width: 960px) {
body {
overflow-x: hidden;
}
}
Should work for modern browsers.
Another solution is to use margin-left: 100%;
And if you wanted to play with the positioning a bit, you can do something like margin-left: calc(100% + 10px);
And another alternate way is to do float: right; and then play around with margin-right -50px; where 50px is the width of the hidden div. You could even have a neat transition if you animate the margin-right if you were making a menu.
I had a similar situation where I needed an absolutely placed element to be positioned partially to the right of the main content header. If the browser was wide enough to show it, I did NOT want to clip it (overflow: hidden;) but I also did not want to make the scrollbar appear if the browser was not wide enough.
Here is the code I used:
#media screen and (max-width: 1275px) {
#header {
overflow-x: hidden;
}
}
Old question, but answering for new visitors. This should do it:
.offscreen {
position: fixed;
height: 100px;
width: 100px;
right: 0px;
top: 50px;
transform: translateX(50px);
}
position: fixed is placing the element relative to the viewport (browser window). Think of fixed as being the same as absolute, except it's the relative to the viewport, ignoring all other divs.
Then we place the element on the top right corner with top: 0 and right: 0
We have this:
______________
| [Element]|
| |
| |
| (Viewport) |
| |
| |
|______________|
Then we move the element to the left by 50px with transform: translateX(50px):
______________
| [Ele|ment]
| |
| |
| (Viewport) |
| |
| |
|______________|
But seeing that the element has a width of 100px and you're moving by 50px, which is half of the width, then it's better to do it like this instead: transform: translateX(50%)
The advantage of using percentages is that even if you later change the width to 120px for example, you won't have to manually the change from translateX(50px) to translateX(60px). By using percentage the math is done for you.
Note: This is not affected by zooming in/out and also does not cause overflow (scrolling).
scroll is may be you have placed relative position property to the containing div and it result the required div to go off the right by -50 but as relative to the main containing div not the browser viewable area.. if its parent div just inside the body tag or the parent div does not include any position property your code should work.. and again you can apply overflow:hidden property to wrapper div to hideout the unnecessary part