In a classic layout (header fixed, main and footer fixed), i would like to center the text of the main element. For the purpose of this exercise, I would like to set the line-height such that it equals the height of the main element, then the text would be vertically centered. The absolutely positioned main element has top and bottom padding of 10%, so it's 80% high.
How can I get the line-height to equal the container height?
* { box-sizing: border-box; }
html { height: 100%; }
body { margin: 0;
font-size: 10px; }
header { border: 1px solid black;
position: fixed;
top: 0;
height: 10%;
left: 0;
right: 0;
}
main { border: 1px solid black; left: 0; right: 0;
position: absolute;
top: 10%;
/* height: 80%; */
bottom: 10%;
line-height: 80%;
}
footer { border: 1px solid black;
position: fixed;
height: 10%;
left: 0;
right: 0;
bottom: 0;
}
<header>Header</header>
<main><div>Main Div</div></main>
<footer>Footer</footer>
You could use an old trick with a pseudo and the div set as an inline-block element and vertical-align. The pseudo is to be 100% of main's height, since it is an absolute element sized via coordonates, the pseudo should take height:100%;
Demo below
* {
box-sizing: border-box;
}
html {
height: 100%;
}
body {
margin: 0;
font-size: 10px;
}
header {
border: 1px solid black;
position: fixed;
top: 0;
height: 10%;
left: 0;
right: 0;
}
main {
border: 1px solid black;
left: 0;
right: 0;
position: absolute;
top: 10%;
/* height: 80%; */
bottom: 10%;
}
/* centering trick */
main::before {
content: '';
height: 100%;
}
main:before,
main>div {
vertical-align: middle;
display: inline-block;
}
/* end centering trick */
footer {
border: 1px solid black;
position: fixed;
height: 10%;
left: 0;
right: 0;
bottom: 0;
}
<header>Header</header>
<main>
<div>Main Div</div>
</main>
<footer>Footer</footer>
But this really not the way to do and this example is not going to teach you anything usefull, today you can easily relay on the flex or grid model to avoid tricky methods .....
Forget about line-height for this kind of visual, this is not the job of line-height and not the way to use it. line-height:80%; means 80% of 1em (the font-size set ).
The easiest way to do this while still using line height to center your text would probably be to use view port units instead of %. Simply set your main section and it's line height to 80vh (or however tall you want it to be).
main {
height: 80vh;
line-height: 80vh;
}
If you aren't familiar with viewport units and how they work, here is a quick explanation with some examples. Good luck!
In this particular case you can rely on vh unit
* {
box-sizing: border-box;
}
html {
height: 100%;
}
body {
margin: 0;
font-size: 10px;
}
header {
border: 1px solid black;
position: fixed;
top: 0;
height: 10vh;
left: 0;
right: 0;
}
main {
border: 1px solid black;
left: 0;
right: 0;
position: absolute;
top: 10vh;
bottom: 10vh;
line-height: 80vh;
}
footer {
border: 1px solid black;
position: fixed;
height: 10vh;
left: 0;
right: 0;
bottom: 0;
}
<header>Header</header>
<main>
<div>Main Div</div>
</main>
<footer>Footer</footer>
Are You Sure You Want to do it with Line Height? It might have certain consequences. See this Pen https://codepen.io/iamrgaurav/pen/xJMpWO
But as Stephen represented it is the way you want to achieve
.footer{
position:fixed;
bottom:0;
}
.header{
position:fixed;
top:0;
}
.main{
position:relative;
top:10px;
height:100%;
line-height:90vh;
background-color:#ddd;
}
<header class = "header">header</header>
<main class = "main">
<div>Main</div>
</main>
<div class = "footer">footer</div>
Setting the line-height won't make text vertically aligned. for horizontal alignment, use text-align: center; in the container.
For vertical alignment, you could use the following CSS since it;s absolutely positioned.
main div {
position: absolute;
top: 50%;
left: 50%
transform: translate(-50%, -50%);
}
Fiddle
Related
I have a body containing two div's one is an absolutely positioned div and another one is a static default positioned div, i want the absolutely positioned div to take the full height of the screen which it takes but the problem that next arises is when i try to apply margin top to the statically positioned div, it also gets added to the absolutely positioned div.
How can I make the absolutely positioned div not get the margin of the sibling div ?
body {
font-family: sans-serif;
margin: 0;
padding: 0;
position: relative;
}
.div-1 {
position: absolute;
border: 2px solid red;
width: 90%;
left: 0;
right: 0;
margin: 0 auto;
height: 100vh;
}
.div-2 {
height: 200px;
width: 90%;
background-color: blueviolet;
margin-top: 8rem;
}
<div class="div-1"></div>
<div class="div-2"></div>
The issue is that you have margin collapse on the body element. Margin collapse happens when there's no content separating parent and descendants elements (such as the body and .div-2). You can easily fix this by setting the display property of the body element to flow-root.
body {
font-family: sans-serif;
margin: 0;
padding: 0;
position: relative;
/* Set flow-root */
display: flow-root;
}
.div-1 {
position: absolute;
border: 2px solid red;
width: 90%;
left: 0;
right: 0;
margin: 0 auto;
height: 100vh;
}
.div-2 {
height: 200px;
width: 90%;
background-color: blueviolet;
margin-top: 8rem;
}
<div class="div-1"></div>
<div class="div-2"></div>
body {
font-family: sans-serif;
margin: 0;
padding: 0;
position: relative;
}
.div-1 {
position: absolute;
border: 2px solid red;
width: 90%;
left: 0;
right: 0;
margin: 0 auto;
height: 100vh;
z-index:1;
}
.div-2 {
height: 200px;
width: 90%;
background-color: blueviolet;
top: 8rem;
position: inherit;
}
Use top and position inherit instead of margin-top, check if it can be use.
I want to use position: absolute to create a centered element, but it will create a horizontal scrollbar on Internet Explorer 11. Please see the script below. Anyone here knows how to fix this problem?
*Update: I figured out that using overflow:hidden seems to solve this problem somehow. But when there are another one outside of the container, it will be hidden as well.
.container {
width: 80%;
margin: 0 auto;
height: 100vh;
border: 1px solid green;
position: relative;
overflow: hidden; /*This one is not the solution, though*/
}
.content {
width: 80%;
height: 30px;
position: absolute;
top: 50px;
left: 50%;
transform: translate(-50%, 0);
border: 1px solid red;
}
.another-content {
width: 40px;
height: 40px;
border: 1px solid blue;
position: absolute;
bottom: 20px;
right: -20px;
}
<div class="container">
<div class="content"></div>
<div class="another-content"></div>
</div>
You need to add following properties with the position absolute in IE
position: absolute;
top:0;
right: 0;
left: 0;
bottom:0; //specify all including bottom:0
The scrollbar show up in all browsers, not only IE. You can do the following:
The biggest issue is that the left: 50% and width: 80% together are adding to the total width and forcing the horizontal scrollbar to show up in some browsers (e.g. Internet Explorer and MS Edge). You set the width to 80%, so divide the remaining 20% between the left and right border and you'll end up with 10% each. Simply use left: 10% to achieve the same result, but without the side effect of the horizontal scrollbar.
Also when you set the size to 100% and then add border, those borders will be out of the view and cause the scrollbars to show up. This is the same in all browsers. Use box-sizing: border-box to force the browser to include the border in the height and width calculation.
The height: 100vh makes the box height equals to the view port. However, the body has default margins which vary from one browser to another. You can either set those margins to zero body { margin: 0; }, or change the height to height: 100% which is 100% of the container which the body in this case.
Try this:
.container {
width: 100%;
height: 100%;
border: 1px solid green;
position: relative;
box-sizing: border-box;
}
.content {
width: 80%;
height: 30px;
position: absolute;
top: 50px;
left: 10%;
border: 1px solid red;
}
<div class="container">
<div class="content"></div>
</div>
Thanks for your replies. Though they are not direct solution, they helped me a lot to figure out how to solve it.
The cause is as what Racil Hilan said. When I use left:50% and width:80%, the content width will be added up and create a horizontal scroll, which is not ignored by only IE. And my point is to avoid creating that added-up width. Here is my two way to workaround this one.
* {
box-sizing: border-box;
}
.container {
width: 100%;
height: 100vh;
border: 1px solid green;
position: relative;
}
.content {
width: 80%;
height: 30px;
position: absolute;
top: 50px;
left: 0;
right: 0;
border: 1px solid red;
margin: 0 auto;
}
.content-wrapper {
border: 1px solid black;
height: 30px;
position: absolute;
top: 100px;
left: 0;
right: 0;
}
.another-content {
width: 80%;
display: block;
height: 100%;
border: 1px solid red;
margin: 0 auto;
}
<div class="container">
<div class="content"></div>
<div class="content-wrapper">
<div class="another-content"></div>
</div>
</div>
Here is what I have so far: http://jsfiddle.net/F8AN4/
I want a border on each side of the div that is vertically centered and is pointing to the left/right sides of the screen. I've seen this done a lot, but can't for the life of me figure out how to do it!
It would look like:
-----|DIV|------
CSS
div {
background: lightgreen;
height: 100px;
margin: 0 auto;
position: relative;
width: 200px;
}
div::after {
border-right: 10px solid black; // not sure how to do this.
content: "";
top: 0; left: 0; right: 0; bottom: 0;
position: absolute;
}
div::before {
content: "";
top: 0; left: 0; right: 0; bottom: 0;
position: absolute;
}
Any ideas?
You will need two wrapping containers: an inner div that holds the content, and an outer div:
<div class="outer">
<div class="inner"></div>
</div>
The CSS is simple — the outer div will need to have 100% width (so that the pseudo-element can stretch to the full width), while the inner div can have a width that you designate later.
.inner {
background: lightgreen;
height: 100px;
margin: 0 auto;
width: 200px;
}
.outer {
position: relative;
width: 100%;
}
.outer:before {
border: 1px solid #000;
box-sizing: border-box;
content:"";
position: absolute;
top: 50%;
left: 0;
width: 100%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
The CSS transform property is used to ensure that the pseudo-element is perfectly vertically centered — it matters when the horizontal line you want is thick.
If you want odd-numbered dimensions for the horizontal line, you can choose to specify the height of a single border, i.e. border-top: 1px solid #000;, or abandon the border property and set the height and background-color. It works either way :)
http://jsfiddle.net/teddyrised/F8AN4/9/
[Edit]: Remove the bottom margin on outer div, it was not necessary for the code to work ;)
FIDDLE
HTML
<div><span>TEXT</span></div>
CSS
div {
margin-top:10px;
height: 1px;
border-top: 1px solid black;
text-align: center;
position: relative;
}
span {
position: relative;
top: -.7em;
background: lightgreen;
display: inline-block;
border-width:0 2px;
border-color:black;
border-style:solid;
}
Is this what you're looking for?
http://jsfiddle.net/F8AN4/3/
I guess there is a more beautiful way to do it maybe someone has a better idea :)
<div id="main">
<div class="hrleft"></div>
<div class="mid"></div>
</div>
div.hrleft {
height: 45px;
width: 200px;
border-bottom: 10px solid black;
float: left;
}
I have to centralize an image in both axis and then add a linkable area to that image's top left area. This works great for webkit and ff but ie fails. My html code is this:
<body>
<div class="content">
<img src="images/main_image.jpg" />
Logo
</div>
</body>
and my css code this:
body, html {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
background-color: #000;
overflow: hidden;
}
div.content {
position: relative;
width: 1001px;
height: 626px;
top: 50%;
margin: 0 auto;
padding: 0;
}
div.content img {
margin: 0;
padding: 0;
display: block;
position: relative;
top: -50%;
}
div.content a {
width: 14%;
height: 9%;
display: inline-block;
position: absolute;
top: -42%;
left: 7%;
text-decoration: none;
margin: 0;
padding: 0;
text-indent: -9999px;
}
this doesn't work for ie because i use an a tag displayed as inline-block positioned accordingly. Our friend ie doesn't show the linkable part in the screen at all because the text-indent. Can someone help a little bit? Thanks. This demo shall help you more i think.
Take a look at this demo (or results only here)
HTML is not changed. I assume that image has the same height/width as content div
CSS:
body, html {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
background-color: #000;
overflow: hidden;
}
div.content {
position: relative;
padding: 0;
border:solid 1px blue;
width: 1001px;
height: 626px;
/*below will center div on screen */
top: 50%;
margin: -313px auto 0;
}
div.content img {
margin: 0;
padding: 0;
display: block;
border:solid 1px white;
/*top:-50% removed. Assuming that image has the same height/width as content div*/
}
div.content a {
width: 14%;
height: 9%;
position: absolute;
/* top: -something changed. Remember that absolutely positioned div is always positioned from closest parent relative div*/
top: 10%;
left: 7%;
text-decoration: none;
margin: 0;
padding: 0;
text-indent: -9999px;
border:solid 1px green;
}
It looks a like you're creating a container, moving it to the bottom of the screen and then moving the image outside of it to the top-left corner of the screen. This last step is exactly what will fail in many cases. Child-elements usually will be hidden or cutted away when leaving their parent container. IE is more restrictive but correct in this case.
You can achieve your goal easier when you'll place the image outside the container. Keep in mind that body is a container by itself that is allways 100% wide and high (and cannot be changed to be 50% or whatsoever).
Here's the result on js-fiddle
The Html:
<body>
this is the body
<img class="my_image" src="images/main_image.jpg" />
<div class="content">
This is the container
<a href="#" >Logo</a>
</div>
</body>
CSS:
body, html {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
background-color: #000;
overflow: hidden;
color:silver;
}
div.content {
color:black;
background-color: silver;
position: relative;
width: 1001px;
height: 626px;
top: 50%;
margin: 0 auto;
padding: 0;
}
.my_image {
width:160px;
height:60px;
border:1px solid red;
margin: 0;
padding: 0;
display: block;
position: absolute;
top: 0;
left:0;
}
div.content a {
color:red;
font-size:14px;
display: inline-block;
position: absolute;
top: 20%;
left: 7%;
text-decoration: none;
margin: 0;
padding: 0;
}
In general it's the best to avoid negative values. They're misinterpreted in many browsers and produce problems.
I have to make a layout with a .header and .content like with fixed height (for example 100px) and 100% width.
Then, I have to put a content with dynamical height that cover the void space.
<!-- [...] -->
<style type="text/css">
body {
margin: 0;
padding: 0;
}
.wrapper {
height: 100%;
width: 100%;
position: absolute;
}
.header {
position: absolute;
top: 0;
height: 100px;
width: 100%;
background: #0F0;
}
.footer {
position: absolute;
bottom: 0;
height: 100px;
width: 100%;
background: #0F0;
}
.content {
position: absolute;
height: 100%;
width: 100%;
background: #F00;
padding: 100px 0;
margin: -100px 0;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="header">
</div>
<div class="content">
</div>
<div class="footer">
</div>
</div>
</body>
</html>
This layout HAD to permit me to put a header and footer with fixed height, and a content with images that scale dimensions (inside a div.content).
First of all: If you have a unique element, like a page header/footer, please use an id and not a class. A class is used for elements that appear frequently or have something in common that makes it semantically correct to group them, like description texts.
Now your problem. We have to give the html and body a total height of 100% so they won't resize and we can be sure that we will use the whole page.
html, body {
height: 100%;
margin: 0;
padding: 0;
}
You then used a wrapper, but we can omit that. <body> is already a wrapper. The header and footer explain their self.
#header {
height: 100px;
position: absolute;
top: 0;
left: 0;
right: 0;
background: #0F0;
}
#footer {
height: 100px;
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: #0F0;
}
The content is a bit tricky. It needs to be expanded to 100% - 100px at the top - 100px at the bottom. Impossible? No.
#content {
position: absolute;
top: 100px;
bottom: 100px;
left: 0;
right: 0;
overflow: hidden; /* No scrollbars | Make this 'auto' if you want them */
background: #F00;
}
Finished. You can have a look at it on jsFiddle.