CSS: set hight to 100% of parent - css

I have some some rows of image thumbs inside anchors inside a div, one div for each row, like this:
<div class="row"><a><img></a><a><img></a><a><img></a></div>
<div class="row"><a><img></a><a><img></a><a><img></a></div>
The images have different proportions, some portrait, some landscape orientation. The max dimensions for the thumbs are 150px (wide or tall), and they are always either 150px wide or high.
I want all images to align with the bottom of their parent .row div.
So if there is any portraits in a row, any landscapes will align at the bottom and have some space above them.
To have the images align at bottom, I position them absolute, and relative to their anchor
To do this, I use the following CSS:
<style>
div.row {
float: left;
clear: both;
}
.row a {
position: relative;
float: left;
width: 175px;
}
.row a img{
position: absolute;
bottom: 0px;
}
</style>
The above works fine and as expected, but it's got a flaw that I'm trying to fix: It requires the height of the relatively positioned anchor tags to be set to a specific size.
I don't want that, because if a row contains only landscape thumbs, I do not want it to be unnecessarily high.
I want each .row div to be the height of the highest image it contains.
If there are only landscapes in a row, the height of that row will be just that of the highest landscape.
I though I would be able to fix this by setting the height if the elements to 100%:
<style>
.row a {
position: relative;
float: left;
width: 150px;
height: 100%;
}
</style>
That would then be 100% of its parent, the .row div. But for some reason, this only works if I specify the height of the .row div, and then I have the same problem (all rows equal hight regardless of actual content:
<style>
div.row {
float: left;
clear: both;
height: 150px;
}
.row a {
position: relative;
float: left;
width: 150px;
height: 100%;
}
</style>
However, since the .row div grows dynamically with its contained images, it actually has the height I'm trying to refer to with my height : 100% for the a tag. But for some reason it does not work.
Why? What am I not understanding here, and how to do this?
I spend many hours on this before turning here, hopefully someone has the golden answer.

It's possibly easier to use inline-block instead of floating. Something like this:
http://jsfiddle.net/cvQAZ/1/
Or do you need the links actually have the same height? Then try a "table" layout (not supported by IE6):
http://jsfiddle.net/DpvgR/1/

Related

Chrome not letter display:table div take 100% height

I have two divs inside a container div using display: flex. One div is meant to simply contain text, and center it as closely to the center as possible. The other div contains responsive content (and image in the demo provided) that basically defines the height of the flex.
The first child div, contains layers of divs to emulate a table using display: table and display: table-cell, along with a height: 100% and vertical-align: middle. Before anyone mentions, I can't use an actual <table> due to problems with it supporting position: relative which my actual site utilizes.
In Firefox and Edge, everything loads as expected and works perfectly (or rather as good as Edge can muster). However, in Chrome, the div using display: table refuses to acknowledge it's height: 100%.
Here is a demo of my problem
Using table tags (or display:table) for layouting purposes is wrong. You should only use tables for displaying tabular data.
What you want can be achieved with these mods to your CSS:
.flex-box {
position: relative;
}
.table {
position: absolute;
width: 100%;
height: 100%;
}
.table .table-cell {
display: block;
text-align: center;
top: 50%;
transform: translateY(-50%);
position: relative;
width: 100%;
max-height: 100%;
overflow-x: hidden;
}
The "cell" is now centered both horizontally and vertically. And it gets a vertical scrollbar if the content overflows the box.
Here's the updated fiddle.

Set line-height as a percentage relative to the parent element

I have a responsive element where it's width and height will both scale. Inside this I have some text which I want to center vertically.
How can I set the text's line-height to be the same as it's parent if I don't know the parent's height?
line-height: 100% is relative to the font's regular height so this doesn't help...
Here's another way to center an element vertically. I came across this technique some time ago. Basically it uses a pseudo element and vertical-align: middle.
.block::before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
}
/* The element to be centered, can
also be of any width and height */
.centered {
display: inline-block;
vertical-align: middle;
width: 300px;
}
Since it's 2019 already, you could also use flexbox to achieve this :)
To do so, add the following classes to the parent element:
display: flex;
flex-direction: column;
justify-content: center;
See this Fiddle
I'd try putting the text inside another element, of which you know (or set) the size. Then setting relative positioning to it, top, left 50% and negative left and right margins.
See this Fiddle
The only problem is that this relies on a known/fixed textblock. If the text is variable, I'm afraid you will have to resort to using Javascript..
Regarding hyperlinks:
I was having this problem regarding links in main menu. And since it was <a> in <li> tags I needed some surface for the links to be clickable/touchable(see touch target size).
So what I did was for the <ul> I set a fixed height(through it's parent in this case), the <li>-s are a percentage of it and the <a>-s have a min-height and line-height properties set to them and it's easy from there to set the top. The code:
.menu-header-main-container{
position: fixed;
top: 0;
bottom: 160px;
}
.menu-header-main-container ul.menu {
height: 100%; }
.menu-header-main-container ul.menu li {
height: 33.33%;
max-height: 110px; }
.menu-header-main-container ul.menu li a {
line-height: 40px;
min-height: 40px;
top: calc(50% - 20px);
position: relative; } }
You cannot set the line-height to 100% of the parent element's height with only CSS. Rather, you can use CSS to center an element vertically.
.parent {
height:150px;
position:relative;
border:1px solid #FDD;
}
.position-center {
position:absolute;
top:50%;
transform:translateY(-50%);
}
<div class="parent">
<span class="position-center">I am vertically centered element</span>
</div>
Wow, 2022 and I don't think we have a decent way to do this still. What I used to do and I think is the less painful idea is to use a table for layout. Tables will naturally center text vertically, or you can use "vertical-align"
<table style="width: 100%; height: 100%; text-align: center">
<tr><td>Your text</td></tr>
</table>
Not great, but at least you can center text without ever having to specify fixed heights.

When Window Size Is Smaller Elements Overlap Eachother?

I have designed a website and am a little bit stumped right now.
If you view the website at:
http://www.noxinnovations.com/portfolio/charidimos/
If you change the size of the window you will notice the Navigation overlaps the logo/header.
Anyway to change this? What I want to do virtually is to make the window have a scroll bar appear if that is possible.
Any ideas?
Thank you :-D.
It's your width: 100%; in your #header element that's causing your strange overflow behavior. Place your #logo and #navigation elements inside of another div with a fixed height and width that sits inside of the #header, then give your #header the property overflow: hidden; and that should fix you right up.
If you want your navigation not to overlap, you can do the following
#navigation {
width: 500px;
height: 100px;
padding-top: 52px;
position: fixed; // CHANGE FROM RELATIVE TO FIXED
left: 770px; // ADD THIS BIT OF POSITIONING (ADJUST AS NECESSARY)
float: right; //REMOVE THIS FLOAT
text-align: center;
vertical-align: middle;
}

CSS position relative and element height

I have one element below another and I am using position relative to drag the bottom element up just a bit so that it overlays the top element.
The paperOverlay element is the last element on the page, vertically speaking, and I want it to extend to the bottom of the browser window. However, the relative nudging of the element's position leaves an equal amount of whitespace at the bottom. Is there any way to avoid this?
The HTML looks like:
div class="container">
<div class="homePage">
<!-- some content -->
</div>
<div class="paperOverlay" style="position: relative; top: -70px;">
<!-- some more content -->
</div>
</div>
And the CSS looks like:
div.container
{
width: 960px;
margin: 0 auto;
}
div.homePage
{
width: 800px;
height: 500px;
}
div.paperOverlay
{
width: 960px;
min-height: 400px;
background: url('Images/Overlay.png') no-repeat top center;
}
Basically, the bottom layer is a white background with a torn paper edge effect at the top. The goal is to have the torn paper edge slightly overlay the bottom of the element above it. I did try margin-top: -70px as suggested below and it fixed the height, but now the elements in the top element lay on top of the overlay, and I want the overlay to be on top.
Could you try a negative margin rather than relative positioning? Also, could you explain a little bit more why you need to do this and post you css so that we can better suggest a solution?
Try setting the height of the paperOverlay element. It should be the actual height minus the amount moved relatively.
I did try margin-top: -70px as suggested below and it fixed the height, but now the elements in the top element lay on top of the overlay, and I want the overlay to be on top.
Try this:
div.container
{
margin: 0 auto;
width: 960px;
}
div.homePage
{
height: 500px;
position: relative;
width: 800px;
z-index: 1;
}
div.paperOverlay
{
background: url('Images/Overlay.png') no-repeat top center;
min-height: 400px;
position: relative;
top: -70px;
/* you can optionally use bottom: 70px; rather than top: -70px */
width: 960px;
z-index: 2;
}
Using position: relative; on both elements and setting the z-index should get the overlay on top of the top element, rather than the other way around.
You may also want to try using display: block; on all elements where you need fixed width/height (especially divs and other containers that need a fixed width/height, like anchors or list items), to prevent collapsing. It will usually resize non-block-level elements to fit their contents and ignore width and height rules otherwise.
Using the "vh" unit worked for me. I could not get it to work with height: calc(100%-50px)
#main-nav{
width: 55px;
background-color: white;
transition: 400ms;
height: calc(100vh - 50px);
}

line-height as a percentage not working

I am having an issue with line-height that I cannot quite get my head around.
The following code will center an image within a div:
CSS
.bar {
height: 800px;
width: 100%;
line-height:800px;
background-color: #000;
text-align: center;
}
.bar img {
vertical-align: middle;
}
HTML
<div class="bar">
<img src="http://27.media.tumblr.com/yHWA4oxH870ulxnoH7CkOSDR_500.jpg" alt="Foo Image" />
</div>
However, if I change the line height to 100%, then the line height does not take effect (or at least does not become 100% of the div).
Example jsfiddle
Does anyone know what I am doing wrong?
line-height: 100% means 100% of the font size for that element, not 100% of its height. In fact, the line height is always relative to the font size, not the height, unless its value uses a unit of absolute length (px, pt, etc).
I know this question is old, but I found what for me is the perfect workaround.
I add this css to the div that I want to center:
div:before {
content: "";
display: inline-block;
height: 100%;
vertical-align: middle;
}
This works every time and it is clean.
Edit:
Just for completion's sake, I use scss and I have a handy mixin that I include on every parent who's direct children I want to have vertically centered:
#mixin vertical-align($align: middle) {
&:before {
content: "";
display: inline-block;
height: 100%;
vertical-align: $align;
// you can add font-size 0 here and restore in the children to prevent
// the inline-block white-space to mess the width of your elements
font-size: 0;
}
& > * {
vertical-align: $align;
// although you need to know the font-size, because "inherit" is 0
font-size: 14px;
}
}
Full explanation:
div:before will add an element inside the div, but before any of its children. When using :before or :after we must use a content: declaration otherwise nothing will happen, but for our purpose, the content can be empty. Then we tell the element to be as tall as its parent, as long as its parent's height is defined and this element is at least inline-block. vertical-align defines the vertical position of self related to parent, as opposed to text-align that works differently.
The #mixin declaration is for sass users and it would be used like this:
div {
#include vertical-align(middle)
}
When you use percentage as the line-height it is not based on the div container, rather its based on the font-size.
line-height: 100% would be an easy way to vertically center elements, if it was calculated in relation to the container, but that would be too easy, hence it doesn't work.
So instead, it is just another way of saying line-height: 1em (right?)
Another way of vertically centering an element would be:
.container {
position:relative;
}
.center {
position:absolute;
top:0; left:0; bottom:0; right:0;
margin: auto;
/* for horiz left-align, try "margin: auto auto auto 0" */
}
might not be pretty, but it's working, and its semantic;
<div class="bar" style="display: table; text-align: center;">
<img style="display: table-cell; vertical-align: middle;" src="http://27.media.tumblr.com/yHWA4oxH870ulxnoH7CkOSDR_500.jpg" alt="Foo Image" />
</div>
display: table-cell gives an element the unique table ablillity to align verticaly (atleast i think its unique)
This is a very late answer, however in modern browsers, assuming that the parent element is 100% of the screen height as well, you can use the vh viewport unit.
FIDDLE
line-height: 100vh;
Browser support
A more modern approach is to use flexbox for this, it is simpler and cleaner. However, flexbox is an entirely different paradigm from what inline-block, float or position used to be.
To align items inside .parent you do:
.parent {
display: flex;
align-items: center;
}
That is about it. Children of flex parents are automatically converted to flex child items.
You should read more about flexbox, a good place to start is this cheat sheet: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
This is the modern solution in which you need to set the following CSS in the container div or outer div.
.outer-div {
display: flex;
justify-content: center;
align-items: center;
}
Another following solution may be applied to the element which you want to make centered vertically. Note that the outer or container div should be
.inner-div {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
text-align: center;
}
Note that the outer or container div position should be relative.
This solution works in IE9 and above. First we set the child's top position to 50% (middle of the parent). Then using translate rule, shift the child up by a half of its actual height. The main benefit is that we don't need to define child's height, it's calculated by the browser dynamically. JSFiddle
.bar {
height: 500px;
text-align: center;
background: green;
}
.bar img {
position: relative;
top: 50%;
transform: translate(0, -50%);
}
You can set line-height based on that element height. If the element height 200px means you need to set line height to 200px to center the text.
span {
height: 200px;
width: 200px;
border: 1px solid black;
line-height: 200px;
display: block;
}
<span>Im vertically center</span>

Resources