After coming back to web-development after a four year hiatus, I am having a tough time vertically aligning the contents of a bootstrap 3 column with the next column. I have tried searching this site as well as generic searches in general and have just not come up with the right solution ... or my search terms are poor.
In the HTML/CSS below, I would like to vertically center the "Page Title" text in the left column. I would like to keep the HTML and CSS as concise as possible while using the Bootstrap 3 CSS, so I just think I am completely missing something simple.
HTML
<div class="row page-header-box">
<div class="col-md-2 col-sm-2 col-xs-3 page-header-title">Page Title</div>
<div class="col-md-10 col-sm-10 col-xs-9 page-header-seperator">
<div class="page-header-description"><small>Standard Text Description</small></div>
<div class="page-header-alt"><small>Additional Text Description</small></div>
</div>
CSS
.page-header-box {
background-color:#3D3D3D;
border-bottom:5px solid #b3b5b8;
margin-bottom:10px;
}
.page-header-title { color:#f79239;text-align:right;vertical-align:middle;margin:10px 0; }
.page-header-seperator { border-left:5px solid #4e2f91;margin:10px 0; }
.page-header-description { color:#febe10; }
.page-header-alt { margin-top:5px;color:#0093b2; }
Here is a jsFiddle ... http://jsfiddle.net/E6LcY/8/
This is one of the few times I have ever posted, so pointing me in the right direction would be great.
I considered deleting this question, but thought the answer could be useful to someone else (like me) that is looking for a possible solution.
I wanted to stay within the Bootstrap 3 framework ... and ended up adding some JavaScript to make the "titled" centered. I figured that Bootstrap 3 basically requires jQuery for some functionality so it was OK.
Now, I am sure there may be a better way, but I did not like the other solutions. Thanks to all that attempted to put me on the right paths.
HTML
<div class="row page-header-box">
<div class="col-md-2 col-sm-2 col-xs-3 page-header-title" id="header-title">Page Title</div>
<div class="col-md-10 col-sm-10 col-xs-9 page-header-seperator" id="header-seperator">
<div class="page-header-description"><small>Standard Text Description Standard Text Description Standard Text Description Standard Text Description Standard Text Description Standard Text Description</small></div>
<div class="page-header-alt"><small>Additional Text Description</small></div>
</div>
</div>
CSS
.page-header-box {
background-color:#3D3D3D;
border-bottom:5px solid #b3b5b8;
margin-bottom:10px;
}
.page-header-title { color:#f79239;text-align:right;margin-bottom:10px; vertical-align: middle; }
.page-header-seperator { border-left:5px solid #4e2f91;margin:10px 0; }
.page-header-description { color:#febe10; }
.page-header-alt { margin-top:5px;color:#0093b2; }
JS (using jQuery)
var sep_height = '';
$(window).on("load resize", function(e) {
var seperatorHeight = $('#header-seperator').height();
if (seperatorHeight != sep_height) {
sep_height = seperatorHeight;
var titleHeight = $('#header-title').height();
var difference = ((seperatorHeight - titleHeight) / 2) + 5;
$('#header-title').css('margin-top', difference + 'px');
}
});
Note: the "sep_height" is just so that I don't make unnecessary calculations and only modify the title height when I need to. I am also adding an additional 5px to the top- margin to compensate for the margins on the description text.
Here is the latest fiddle (with a fix for the onLoad event): http://jsfiddle.net/E6LcY/15/
Thanks again to all those who helped.
Add the rule: line-height: 45px; to the col-md-2 class
UPDATED FIDDLE
This is how i do, you can try this:
.Parentdiv{
position:relative;
width:100%;
height:100%;
}
.Parentdiv .childdiv{
position: absolute;
top:0;
bottom:0;
margin:auto;
}
I'm starting to get tired of bootstrap in certain aspects somehow. Sometimes the amount of hacking required to accomplish certain functionalities is not worth the supposed benefits you get from using it.
In this case, I ended archiving the functionality I needed by abandoning bootstrap and using a combination of flexboxes with those properties applied to the parent:
.parent {
display: flex;
flex-wrap: wrap;
align-items: center;
}
those to the children:
.parent > div {
display: inline-block;
vertical-align: middle;
}
and this media query:
#media all and (max-width: 500px) {
.parent {
/* for small screens, we use column direction rather than row */
flex-direction: column !important;
}
}
The html involved is like this:
<div class="parent">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
I used this, for instance, for a responsive footer. Playing with a combination of some fixed width and margin (same for each), they get nicely aligned on top of the others in different quantities per row depending on the width of the screen, until it is narrow enough to just show them in one row.
In my opinion, much clearer, easier, cleaner and less code, with better responsiveness, better layout support, avoids using javascript and without all the overhead and hassle of bootstrap.
Related
For a webpage grid-layout I decided to use Flexbox. Now I wanted to implement some "auto-functionality", so that grid-boxes can later be inserted without the need to add classes or styles in the HTML. One of this features is to make a box allways be 75% as tall as it is wide - even if the box is resized by, for example, browserwindow resize. Off course, if the boxes content extends the 75%-height, it should (and only then should) increase its height to fit the content. I searched for hours to find a suitable solution, but I finally got it working. So I thought at least, until I added content to the box.
The auto aspect-ratio works fine, as long as the box is empty. If I add content, the 75% of the width is allways added to the height it has through extension by its content. I made a jsfiddle to clearly visualize the problem:
JSFiddle wd5s9vq0, visualizing the following Code:
HTML-Code:
<div class="container">
<div class="content-cell"></div>
<div class="content-cell"></div>
</div>
<div class="container">
<div class="content-cell">
This cell has an inreased height because of
it's content. The empty space below the
content is the 75% of the cells width.
</div>
<div class="content-cell"></div>
</div>
CSS:
.container {
display: flex;
width: 400px;
}
.content-cell {
flex: 1 1 0;
margin: 10px;
background-color: #ccc;
}
.content-cell::after {
content: "";
display: block;
padding-top: 75%;
}
If I didn't knew it better, it looks like a floating-problem - but I think the ::before / ::after selector should add the block-element before the element it is used on and not inside it.
Does anyone has an idea on how to fix this problem?
This seems to be a very widespread problem on the internet, and most solutions you find are either about wrapping the content, absolute-positioning the content or a mixture of both. This has numerous and case-dependent downsides. After hours of playing around with the code, I finally found a combination of CSS proporties that work without the need to add any DOM or make the content absolute-positioned. This looks quit basic, and I am wondering why it took me so long and why you can't find it out there on the web.
The HTML:
<div class="mybox aspect-full">
This is text, that would normally extend the box downwards.
It is long, but not so long that it extends the intended aspect-ratio.
</div>
The CSS:
.mybox {
width: 200px;
}
.aspect-full::before {
content: '';
display: block;
padding-top: 100%;
float: left;
}
The only downside I could find is that the content of your cell must float. If you use clear on one of your child objects, it is positioned below the expander-block and you are back to the original problem. If you need to clear the floating of divs inside of these aspect-ratio-cells, you might consider to wrap them and keep the wrapper floatable.
I'm trying to format a slide in a bootstrap that has the format of the following fiddle: fiddle
The two divs with "hidden" in them are meant to disappear when on desktop so that when someone is using a tablet or phone they stack on top of each other. This works fine in the fiddle where the height is set to a fixed number
height: 100px;
But I don't want to set the height this way. If I remove this line you can see in the fiddle that "hidden2" drops down in a weird way instead of acting as a spacer for the text content on the bottom. I've also noticed if I remove the img tag the grid works fine.
I'm not sure why it does this and with real content it just looks like there's no spacer and all the text hugs the left side. Any ideas?
Edited: You can have a width of the content so there is space on both sides, and using the bootstrap grid system drop the text content down.
HTML
<div class="whole">
<div class="col-xs-12 col-sm-4 col-md-4 col-lg-4">
<img src="http://placehold.it/100x100"/>
</div>
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-8">text content</div>
</div>>
CSS
div {
height: 100px;
background: red;
border: 1px solid black;
text-align: center;
}
img {
border-radius: 50%;
}
.whole {
margin: 0 10%;
width: 80%;
}
As much as i understood from your question, you're trying to preserve the functionality found on the fiddle link you provided, but also preserving equal heights. I also understand that you do not want to assign the height manually (i.e in your case, hard-coded).
There are two ways of approaching the solution: Javascript or CSS3.
Javascript:
I usually wouldn't solve layout issues with Javascript, but since your scenario has more than one row invloved, the easy way is JavaScript. With the help of jQuery, you can iterate through the div elements, having an initialized variable (example: var bHeight = 0). Check for each element's height; if it's greater, assign it to bHeight.
Your code should something like this:
$(document).ready(function(){
var bHeight = 0;
$("div").each(function(){
if($(this).height() > bHeight)
bHeight = $(this).height();
}); //end of loop
//now, assign height to all
$("div").height(bHeight);
});
This method will allow you to assign the height of your columns dynamically.
CSS3:
A little research online cold introduce you to the CSS3 display: flex, yet it's totally up to you to decide regarding browser support (CSS flex Property), and more details on solving your issue here: (A Complete Guide to Flexbox)
I have markup that goes something like this
<div class='wrap'>
<div class='container'>
Body Container content
</div>
<div class='container'>
Footer Container content
</div>
</div>
I want to display a header containing, amongst other things, a logo above the first, body, container. This I accomplished by defining
.container::before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
The above works. The problem is that the logo ends up not onlyu above the body content but also above the footer content which is not quite the desired result. I have played around with various combinations of
.container::before:nth-of-child(1)
{
}
.container:nth-of-child(1)::before
{
}
but I haven't quite found the right syntax to target the ::before pseudo element for the first .container instance. I hope that someone here will be able to tell me how it should be done.
If the worst comes to the worst I can do it with a spot of jQuery but I would like to avoid that.
Would you consider using <main> W3 4.4.14 The main element and <footer> 4.4.9 The footer element per HTML5 elements with class of .container on each? That way you can reference/target those elements without psuedo elements
main::before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
This way the header/logo you are looking for would only appear above the first container only. Then if you need to apply pseudo elements to <footer> you could do something like:
footer::before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
OK so I'll add another answer because it doesn't appear that anyone has solved all of your issues.
First, there is a typo in your css: background-image(url(path/to/image.jpg) is missing the closing paren.
To do what you want, however, there is a simple css selector :). In your example, you try nth-to-child(), but the correct syntax for what you want is nth-child(). Look below for two options, with a working demo.
.container:first-child:before
{
display: block;
content: "Before Element";
/* other styling that you choose*/
}
/* the following selector will also work
.container:nth-child(1):before
{
display: block;
content: "Before Element";
}
*/
<div class='wrap'>
<div class='container'>
Body Container content
</div>
<div class='container'>
Footer Container content
</div>
</div>
Note that the display: block; part is so that the before content appears on it's own line, since :before elements by default are display: inline-block;.
I dont think that there is a way to making it work with nth-of-child, but it will definitely work with first-child (if you always need it only in the first element with class .container):
.container:first-child:before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
My first thought here is that there should be an additional class for the header, or use the <header> and <footer> elements in place of divs. For example:
<div class="wrap">
<div class="container header">
Header
</div>
<div class="container footer">
Footer
</div>
</div>
and
.header::before {
// stuff to make your logo
}
However, if for some reason you can't change the html, then the :first-child selector should work for your needs, as others have answered.
If you want to use nth-child() you need to add it to the parent of the element that you want to select. In this case .wrap.
.wrap:nth-child(1):before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
Can anyone assist me with the following div layout? I have tried a couple of solutions, however, the only way i have been able to accomplish this is using tables.
I had a look at Holy Grail 3 Column Layout, however, this layoyt is not 100% height, and header is not fixed, i also need only the content to scroll, the sidebars needs to be fixed 100% height
It seems the answers here ignored most of your requirements. I stumbled upon this because I am having a rendering issue with the same layout you are after. I forked the fiddle above to show you:
http://jsfiddle.net/RsRf9/2/
The major difference is that the entire body is scrollable, not just the tiny area in the center (I think this is what you are after).
Aside from cleaning up styles that weren't doing anything (like floats while position fixed), the major change is to the center col - all you should need is this:
.center{margin:100px 200px;}
The other change is how you get that "height 100%" effect on your sidebars - my trick is to do this:
.left,.right{width:200px;top: 100px; bottom: 0px;position: fixed;}
Instead of height 100%, I simply tell it to stretch from top 100 (the bottom of the nav) to bottom 0 (the bottom of the page)
That will push the content bellow the top nav and in between your two fixed side bars.
I have created a working fiddle as per your requirements:
Here is working fiddle - UPDATED to include fixed header ONLY TOP BAR IS FIXED
The important thing to note is the structural layout of the divs... notice that the .center is AFTER the .right
<div class='wrap'>
<div class='head'>Header</div>
<div class='bodywrap'>
<div class='left'>left</div>
<div class='right'>right</div>
<div class='center'>center center center center center center center center center center center center ... blah</div>
</div>
</div>
and the css is:
JUST HEADER FIXED:
html,body{height:100%}
.wrap{width:100%;height:100%;position:relative}
.head{height:100px;position:fixed;top:0;left:0;width:100%} << UPDATED for fixed header
.bodywrap{margin-top:100px;width:102%;margin-left:-1%} << UPDATED - Terrible hack and you may find something more elegant
.left,.right{width:200px;height:100%}
.left,.center,.right,.bodywrap{height:100%}
.left{float:left;}
.center{margin-left:200px; overflow:scroll; overflow-x:hidden;}
.right{float:right;}
.left{background-color:#aaa}
.right{background-color:#ccc}
.center{background-color:#444}
.head{background-color:#777}
HEADER AND SIDEBARS FIXED (Also was able to fix dirty hack for .left and .right undersizing
html,body{height:100%}
.wrap{width:100%;height:100%;position:relative}
.head{height:100px;position:fixed;top:0;left:0;width:100%}
.bodywrap{margin-top:100px;margin-left:-8px}
.left,.right{width:200px;height:100%}
.left,.center,.right,.bodywrap{height:100%}
.left{float:left;position:fixed}
.center{margin-left:200px; overflow:scroll; overflow-x:hidden;margin-right:191px}
.right{position:fixed;right:0}
.left{background-color:#aaa}
.right{background-color:#ccc}
.center{background-color:#444}
.head{background-color:#777}
Here is with top and sides fixed center scroll liquid center column (and no gaps on .left and .right)
It's basic use of floats but the structural markup layout is key ;)
I use the YUI grids style sheet for this kind of layout. It is tried and tested and works in multiple browsers.
This is actually quite easy to do in a rudimentary sense, you don't need tables (or table-cell) but mixing px and % sizes can be problematic. If you stick to % your page will resize better anyway. Handling the cross browser issues takes a bit more CSS tweaking, but there are plenty of grid solutions out there that implement tried and tested solutions even for IE6 and frameworks like twitter's bootstrap will offer a lot more on top.
In other words, this is a solved problem, but here's a quick example of how you can get there by hand;
<div class="container">
<div class="header">
header
</div>
<div class="left">
left
</div>
<div class="main">
content
</div>
<div class="right">
right
</div>
</div>
And the CSS;
html, body, .container
{
height:100%;
}
.container
{
background-color: pink;
}
.header
{
background-color: yellow;
height:50px;
}
.left
{
background-color: red;
float:left;
width:10%;
height:100%;
overflow: hidden;
}
.right
{
background-color: blue;
float:left;
width:10%;
height:100%;
overflow: hidden;
}
.main
{
background-color:#fefefe;
float:left;
height:100%;
width: 80%;
overflow-y:scroll;
}
And of course the Fiddle
Using % sizing will also allow you to approach a more responsive design that works for tablet and mobile. Again, many of the grid frameworks out there are 'responsive' in design.
You can use scrollToFixed plugin for left-sidebar and right-sidebar fixed and center column content only scroll up side and downside.
For demo scroll use below link
http://bigspotteddog.github.io/ScrollToFixed/
And one more thing use Bootstrap for design UI.
Include Bootstrap CSS and JavaScript in your page header part
<div class="container">
<div class="col-md-12">
<div class="col-md-3" id="left-sidebar">
left-content
<div>
<div class="col-md-6" id="center">
center content
</div>
<div class="col-md-3" id="right-sidebar">
right-content
</div>
</div>
</div>
You can modify as per your requirement. I just give you general hint.
Just write below script for scrolling
$(document).ready(function(){
$('#right-sidebar').scrollToFixed({
marginTop: function() {
return 5;
},
limit: function() {
return (
$('#footer-widgets-bg').offset().top - $('#right-sidebar').outerHeight(true)
);
},
zIndex: 1,
removeOffsets: true
});
});
I'm trying to convert my site from using tables to just using css and divs but I'm running into a lot of problems with trying to figure how to exactly do it, I've been looking for tutorials on centering a site with css and how to put divs side by side but I can't really find one that does both and I keep getting confused by how to exactly achieve this, I asked around a bit and I got told to use absolute positioning but still I can't really wrap my head around this.
So basically how would I arrange the 2 central div side by side while keeping the whole thing centered in the browser? The following image is the layout I'm trying to achieve:
the blue boxes are eventual other stuff I might want to put in them, such as a blog requiring again the use of side by side divs.
right now I have the following layout:
<div id="wrap">
<div id="banner"> banner </div>
<div id="navbar"> navigation links </div>
<div id="body"> stuff </div>
<div id="footer"> stuff </div>
</div>
General idea: http://jsfiddle.net/JjbJE/
A little specific but provide you a great adventure to learn HTML | CSS : http://jsfiddle.net/JjbJE/3/
float:left|right this property does the side by side trick
clear:both this property clear away the float property
Other things are pretty easy to learn, just head to W3Schools
First you need a main container to center everything. Then two separate divs. See the HTML below:
<div id="main">
<div class="box">Left Box</div>
<div class="box">Right Box</div>
<div class="clear"></div>
</div>
Here is the CSS you will need:
#main{
width:960px;
margin:0 auto;
}
.box{
width:450px;
float:left;
border:solid 1px #000000;
}
.clear{
clear:both;
}
Hope that helps.
Here's my general overview on converting to a CSS based layout - if you have a table based layout, this is a good plan - in the end you can do more, Google will like you more, and it's much cooler.
My strategy is to look at all the groups of things on your page. Whatever needs to go into a group together, put inside a div. Assign this div a class and/or id to style it. If the divs are grouped, put them together in a div too.
In your case, you have two chunks of content to group inside of divs. Style them to be the size and shape you like, background, border, whatever is needed. Then group them together in an additional div, and center it. This and the rest of the page content can go inside a container div, which will determine the width of the page, how it's aligned, etc.
One possibility is to have a centered wrapper class and contain the divisons inside of that:
<div class="wrapper">
<header></header>
<div id="middle">
<div class="main-article clearfix"></div>
<aside></aside>
</div>
<footer></footer>
</div>
Then to style, center the wrapper, float the aside and main-article:
.wrapper { width: 1024px; margin: 0 auto; /* the auto centers it */ }
header, footer, aside, { display: block; }
.main-article { width: 50%; float: right; }
aside { width: 50%; float: left; }
.clearfix:before, .clearfix:after { content: ""; display: table; }
.clearfix:after { clear: both; }
.clearfix { *zoom: 1; }
Note: This is untested, and uses the clearfix from the HTML5 Boilerplate.
Update 01.22.2014: This "Holy Grail Layout" has ben solved by Flexbox. Check out Solved By Flexbox for more information on recreating this layout (and many more).