I have a main element I have set to position: relative. This contains two divs that I then apply position: absolute on. This then causes the header and footer that sandwich the main element to then bump up against each other. How can I stop this?
Using floats and clearing the footer seems to give the two column layout I want. But I'm not sure how “sturdy” a solution that is and what'll happen on IE6/7.
Code on codepen.
All you elements in main are absolutely positioned, so main's height computes to zero, so the bottom edge of the header is next to the top edge of the footer. If you add a height to main you will open up space between the header and footer.
Given the following HTML:
<header>Header</header>
<main>
<div id="text">
<p>Some text</p>
</div>
<div id="links">
<ul>
<li>Link 1</li>
<li>Link 2</li>
</ul>
</div>
</main>
<footer>
<p>Footer</p>
</footer>
You can realize a two-column layout using floats as shown in the following CSS:
main {
position: relative;
height: auto;
overflow: auto;
border: 1px solid blue;
}
#text {
float: left;
width: 500px
}
#links {
float: left;
width: 400px;
}
You need to set overflow: auto on your main container to contain the floats (equivalent to clearing them).
Also, make sure that the widths of the floated element are not too wide or else they will wrap to a 2nd line if the screen size is too narrow.
See demo at http://codepen.io/anon/pen/gGsjd
Footnote: Using overflow:auto versus clear:both
I tend to use overflow: auto but in some cases the the clear property is what is needed. At some point, read up about "block formatting contexts" at http://www.w3.org/TR/CSS2/visuren.html#block-formatting The reasons to pick one approach over the other are a bit subtle and the choice depends on the details of the layout that you are trying to achieve, how it behaves in a responsive manner and so on.
Related
Many similar questions have been posted to try and achieve position sticky with an element that has flex rules applied (e.g. this post is one of many that I tried the answers from), but my aim is to apply position:sticky to a child of a flex element.
I have a two-column layout with a menu on the left. The idea is that when the page is scrolled down, the blue-colored menu stays at the top (although the image above should scroll upwards, leaving just the menu visible in it's place).
However, no matter of which combinations of align-self I apply, the menu still disappears vertically upwards with the image.
If its possible to combine flex with sticky, then I'm hoping there's also a solution for the child element.
Fiddle here using SCSS
.PageContainer {
.OuterContainer {
display: flex;
flex-wrap: nowrap;
gap: 1em;
.SideOne {
background-color:#fee;
align-self: flex-start /* Solution from https://stackoverflow.com/questions/44446671 */;
width: 10em;
.CompanyLogo {
img {
width: 100%;
}
}
.MyStickMenu {
border:1px solid blue;
background-color:#eef;
position: sticky;
top: 0;
}
}
.SideTwo {
background-color:#ddd;
flex-grow: 1;
flex-shrink: 1;
}
}
}
<div class="PageContainer">
<div class="OuterContainer">
<div class="SideOne">
<div class="CompanyLogo">
<img src="https://via.placeholder.com/250x100.png" alt="" />
</div>
<div class="MyStickMenu">
<h2>
Not-so Sticky Menu
</h2>
<ul>
<li>
Home
</li>
<li>
Away
</li>
</ul>
</div>
</div>
<div class="SideTwo">
<h1>
Scrollable page
</h1>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
</div>
</div>
</div>
Your issue is not with the sticky property but with the expectations you have of it. A sticky element is only sticky within its parent and so the Side One's height limits how far the menu can go.
You're going to have to put the Menu as a sibling to the "sides".
Alternatively you could divide Side One into two separate sides one for the menu and one for the rest, applying the position: sticky to the new side as it is the one who is supposed to cover its siblings while scrolling.
I'm building an angular application that frequently uses nested views. Certain views, however, are taller than the other elements on the page and end up extending well beyond the end of the parent view.
I'm using Ryan Fait's Sticky Footer so I have a wrapper around a containing div set to height:100% and I would have expected the page to just adapt and move the footer to the bottom of the nested view however I'm seeing the style elements of the footer border and background-color are remaining at end of the parent div while the content of the footer is being pushed to the end of the nested div.
Including an image as I'm struggling with getting the language exact:
I'm really looking for any solution from fixing the css to something that seems hackier like changing the footer or using ng-if/ng-class on certain pages. I'm imagining I'm misunderstanding something about CSS/UI-Router but I can't really track it.
The code isn't really interesting but here is it?
CODE
.wrapper {
min-height: 100%;
margin-bottom: -50px;
}
.push {
height: 50px;
}
.footer {
display: block;
height: 50px;
}
.nested {
max-height: 500px;
}
<body>
<div class="wrapper">
<div>
<h1>Some text</h1>
<ui-view class="nested"></ui-view>
</div>
<div class="push"></div>
</div>
<footer class="footer">
<span>some copy</span>
</footer>
</body>
If you use percentage values for height (i.e. a relative height), the parent element heights have to be defined too. In your case you also need height: 100% on body and html, like
html, body {
height: 100%;
}
I have a clear floats problem I can't figure out. This is the HTML code:
<div id="main">
<div id="primary">
<div id="content" role="main">
</div><!-- #content -->
</div><!-- #primary -->
<div id="secondary">
<div><!-- #secondary -->
</div><!-- #main -->
This is the CSS for each element:
#main {
clear: both;
}
#primary {
float: left;
width: 100%;
margin: 0 -40% 0 0!important;
}
#content {
background: none repeat scroll 0 0 white;
box-shadow: 0px 10px 10px 2px #888;
float: left;
margin: 0 12.3%!important;
position: relative;
width: auto;
}
#secondary {
float: right;
margin-right: 15%;
width: 22%;
position: relative;
padding-top: 170px;
}
The website is build on wordpress so main starts in header.php and ends in footer.php. The primary and content divs start and end in each page template and the secondary div is called in each page template (get sidebar) after the primary div ends.
The problem is that the content div stops right after the primary div ends, while the secondary div goes on extending below. The content div should extend until the end of the document where the secondary or main div ends.
You can view the code live and the problem it's causing on this website.
Its because of float
give overflow property to your parent.
or create an extra div and give clear:both
One of the common problems we face when coding with float based layouts is that the wrapper container doesn't expand to the height of the child floating elements.The typical solution to fix this is by adding an element with clear float after the floating elements or adding a clearfix to the wrapper. But you can also use the overflow property to fix this problem. It's not a new CSS trick either. It's been documented before long long ago.
I think the problem is that the 'secondary' element isn't contained within the 'content' element' on your site so obviously 'content' won't grow to accomodate 'secondary'.
You need to have a rethink of your html structure.
Parent elements are never to expand to contain floated elements. To have that element expand to contain them, you add overflow: auto to the parent so the floated element overflowing the element will be contained in most cases. I was unable to find an element to apply that to so you may have done other things to cause this. position:absolute has the same issue where it is taken out of the normal flow and parent elements will not contain them.
The clear property in css needs to be applied to a new div in your code. It works by starting the div below all floating elements within the parent element. It would look something like this:
<div id="main">
<div id="primary">
<div id="content" role="main">
</div>
</div>
<div id="secondary">
<div>
<div style="clear: both"></div> <!-- Don't do inline styles -->
</div>
That should do it. You also should take out the clear: both on #main's CSS. It's not necessary.
i have a few problems setting up a layout with horizontal sections that should have an automatic height depending on it's content.
This is my page structure.
<div id="#page-wrap">
<header>
<div class="inner">
#navigation
#logo floated right
</div>
</header>
<section id="services">
<div class="inner">
#some floated boxes
</div>
</section>
<section id="main">
<div class="inner">
#secteion content
#aside sidebar
</div>
</section>
<footer>
<div class="inner">
#footer stuff
</div>
</footer>
</div>
header, sections and footer are always 100% wide.
each section has a .inner div which is centered with margin: 0 auto.
.inner {
margin: 0 auto;
padding: 96px 72px 0;
width: 1068px;
color: #3C3C3C;
}
and as example this is my header:
header .inner {
background: #fff url('images/years.png') no-repeat top right;
position:relative;
/*height:100px;*/
}
#logo {
position:absolute;
right:70px;
top:15px;
float:right;
}
THE PROBLEM: if i don't set the header to a specific height the background image get's cut off. If i inspect the header with a develper tool like firebug the navigation inside of it is kind of outside the the header-box. So if i don't set the height of 100px the horizontal navigation cuts off the the background image - even though it's in the same header.
any idea what i have to consider here.
you state that it should have an automatic height depending on its content and then later state the problem is the background gets cut off. so, what exactly are you looking for? a min-height of 100px which expands if the content is larger? or did you expect the nav to be 100px in height (thus forcing the header to 100px)? its a bit confusing... at any rate, the header will have a height of zero if the height is not set and it's children are floats. it sounds to me as if you want the header to be 100px for the purpose of showing the entire background - if so, just set the headers height to 100px (as you've done)
edit// you've also stated that the logo is floated, but then show that its positioned absolutely - which is it? and how is the nav positioned? more information is needed
header, section and footer elements are not container elements - if you want them to behave as if they were you have to set them display: block - this will make them to behave as normal div would
I think this may be a clearfix issue--
you could try adding <div style="clear: both;"></div> before you close your header, or add the following properties to your header
.header {
overflow: hidden;
display: inline-block; /* Necessary to trigger "hasLayout" in IE */
display: block; /* Sets element back to block */
}
however if your navigation will have things that hang out of its container sometimes (like a dropdown), it's best to use something like the method at http://www.positioniseverything.net/easyclearing.html.
finally, you can also try wrapping the whole thing (header, and content) in another div which will only have the background property. that way the bg image will not get cut off.
I'm trying to have 2 seperate DIV's, one with Right aligned content (the labels) and the other div with Left aligned content (the content for each label).
I am hoping to make each label "connected" with it's child content on the right so that if it gets pushed down by content from above they will still remain together.
What would be the best way to approach setting this type of layout that is cross-browser? (I have provided in a JPG below).
The alignment is going to be tricky if you actually have the right aligned content in that separate div, especially if the content is variable in nature and the height is prone to change.
Very basically, here is what I would do just so that the right hand features always line up with their associated left hand content. You're obviously going to have to tweak it to your taste.
CSS:
ul {
list-style: none outside none;
margin-left: 150px;
}
ul li h3{
position: absolute;
}
ul li span {
position: relative;
display: block;
width: 150px;
text-align: right;
left: -150px;
}
HTML:
<ul>
<li>
<h3><span>Feature 1</span></h3>
<p>Content 1<br />Content 1</p>
</li>
<li>
<h3><span>Feature 2</span></h3>
<p>Content 2<br />Content 2</p>
</li>
</ul>
I literally just threw this into an empty file just to make sure it works. I know it's not exactly what you asked for, but maybe it will give you some ideas.
As I'm being accused of providing an overkill solution, here's a simpler one just using floats:
CSS:
.left, .right {
float: left;
}
.left {
clear: left;
width: 150px;
text-align: right;
}
HTML:
<div class="left">feature</div>
<div class="right">content<br />content</div>
<div class="left">feature</div>
<div class="right">content<br />content</div>
This is semantically a table, and is an appropriate use for the HTML table layout. While it's important to move away from the use of tables for non-tabular layout, a table is still a table, no matter how few rows or columns. A table with two columns and lots of rows is very prevalent in the real world.
Seems you can also have classes within the divs aligned left or right within the parent element.