Div height and position with inner div display inline-block - html

I'm trying to figure out how is the inner div position, when it's displayed as inline-block and the outer div has line-height set.
<!DOCTYPE html>
<html>
<style>
.outer {
line-height: 20px;
width: 30px;
border: 1px solid black;
}
.inner {
display: inline-block;
width: 20px;
height: 5px;
border: 1px solid green;
}
</style>
<body>
<div class='outer'>
<div class='inner'></div>
</div>
</body>
</html>
https://jsfiddle.net/L4przovt/2/
What is surprising here is the positioning of the inner div. I'd expect it to be on top of the outer div but instead it's somewhere in the middle. Could you explain to me what makes it being positioned in this place?
This is possible duplicate of font-size vs line-height vs actual height but my question seems to be more specific. Please tell me if you think that previous answer should be enough for me.

The .inner div is set to display: inline-block. That activates the vertical-align property, which applies only to inline-level and table cell elements.
The default value for vertical-align is baseline. So that's what you're seeing – the inner div aligns to the baseline of the content.
To fix the problem, add this to your code:
.inner {
vertical-align: top;
}

Related

Child elements outside parent div

It appears that all the elements nested inside my parent divs are overflowing from the bottom border of my parental divs.
As you can see the image divs overlay the parent and the paragraph on the header
Similar questions have to deal with floating elements, but this is not the applicable here since I don't use those
Why is "position:relative" ?
Here is the code,
and a ready fiddle for your, very much appreciated ,tweaks.
https://jsfiddle.net/r96fxfgj/
<!DOCTYPE html>
<html>
<title>DISSECTIONS</title>
<head>
<link rel="stylesheet" type="text/css" href="dissections.css">
</head>
<body>
<div id="header">
<p><span>/<sup>*</sup></span>DISSECTIONS</p>
</div>
<div id="main">
<div class="photo" id="one"> </div>
<div class="photo" id="two"> </div>
<div class="photo" id="three"> </div>
<div class="photo" id="four"> </div>
<span class="stretch"></span>
</div>
<div id="footer">
<button id="about"> ABOUT </button>
<button id="contact"> CONTACT </button>
</div>
</body>
</html>
body {
overflow: hidden; /*prevents scrolling*/
font-family: courier;
}
div {
width: 98vw;
}
p{
font-size: 8vh;
}
span {
font-size: 15vh;
}
sup {
font-size: 8vh;
}
#header {
border: 2px solid black;
height: 20vh;
padding: 0;
}
#main {
border: 2px solid red;
height: 60vh;
margin-top: 5vh;
margin-bottom: 5vh;
padding: 0;
text-align: justify; /*justify*/
}
.stretch { /*justify*/
width: 100%;
display: inline-block;
}
.photo {
border: 2px solid black;
height: 100%;
display: inline-block;
vertical-align: top;
width: 20vw;
margin-left: 1%;
margin-right: 1%;
background-repeat: no-repeat;
background-image: url(
http://www.publicdomainpictures.net/pictures/10000/nahled/1001-12380278201dXT.jpg);
}
#footer {
border: 2px solid blue;
height: 10vh;
bottom: 0;
}
There are a few separate but similar issues here. Most boil down to you're unintentionally setting a specific height for the parent which is smaller than the things it contains.
In general it's best to set specific heights or widths only when your design actually needs those specific sizes -- otherwise just let the content flow dictate the size of its parents.
text in header overflowing the container: Fonts are a bit weird when it comes to sizing -- the value you put in font-size will match the text itself, but will also scale the padding above and below the text to a (typically) larger value (this is in addition to the normal padding attribute found on other elements). You can fix this by setting values for the text's line-height (a cheap but often-used hack for short headers is line-height:1px, which will remove all the extra padding. Don't use this if there's any chance the text will wrap to a second line, though, or the second line will overlap the first.)
images overflowing #main: you're setting #main as a percentage of the viewport height, but images at 100% of their actual size -- so depending on the window size the images may end up larger than or smaller than the container. Either use the same units for both, or don't set a height on #main at all (therefore letting the images dictate the height of the container.)
position:relative -- I don't see this in your code but I've seen it confuse a lot of people: position:relative counterintuitively doesn't affect the DOM node you attach it to, it affects the absolute-positioned children of that node. If a parent has position:relative, then any children with position:absolute will be placed relative to the parent's position instead of relative to the full window. If you're not using position:absolute (and you shouldn't unless absolutely necessary!) then you don't need position:relative.
This seems to be a box sizing problem.
Add this snippet to the top of your CSS (I always include it in my CSS reset), so that every element includes its children's padding and borders in its width/height:
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
If you don't want to apply it to everything, you can apply the styles instead to your .main and .photo classes.
As for your header, the content is overflowing because you have a set height, if you set the height to auto the header height adapts. However if you want to preserve the height of the header, you can change the overflow property to overflow:hidden, which hides overlapping content; or overflow:auto which adds a scroll bar on overflow.

Make the width of outer div to fit inner divs automatically

I have 2 inner divs inside an outer div, and I want to make the outer div to automatically fit to the width of the inner divs. Is that possible?
body {
font-size: 0;
}
#outer {
border: 1px solid black;
}
.inner {
font-size: 12px;
display: inline-block;
border: 1px solid red;
}
<div id='outer'>
<div class='inner'>text1</div>
<div class='inner'>text2</div>
</div>
Your outer div is a block-level element. You need to make it an inline-level element. Inline elements automatically take the size of the content it contains. In terms of the question you've asked, just setting :
display: inline-block
on your outer div will do the trick. See the code snippet below for the demo :
body {
font-size: 0;
}
#outer {
border: 1px solid black;
display: inline-block;
}
.inner {
font-size: 12px;
display: inline-block;
border: 1px solid red;
}
<div id='outer'>
<div class='inner'>
text1
</div>
<div class='inner'>
text2
</div>
</div>
Hope this helps!!!
Add "display: table;" to the #outer css:
For example:
#outer {
border: 1px solid black;
display: table;
}
using display: table is less intrusive as using inline
If you add position:absolute; or float:left; to #outer it will size to the two inner div's. For this instance, I would use the float. Floats are generally better for content that might change or expand/shrink with edits over time whereas absolute positioning should be used outside of the document flow or structure of the document, like a nav bar.
Edit: If you don't need other elements to flow around the outer div the display:inline-block method posted below will work, but if you have elements you want to flow around #outer then float:left would be the way to go. Say you have #outer as 50% of the width and want something else on the other half of the page using display:inline-block will put other elements below #outer.
CodePen link to show difference

css : prevent div width from expanding to available width

How can I prevent div from expanding? I want div with elements not to take 100% of available space and have width that it's children have. I need this for centering parent div horizontally. The trick is that child elements should share float:left or diplay: inline-block and fluid width, so there can be few rows of child elements.
I can not wrap each row in its own div since it will break responsive design.
You should use display: table; It will shrink to the size of it's contents and can also be centered and positioning without having to assign a given width.
DEMO http://jsfiddle.net/kevinPHPkevin/9VRzM/
You can set the width property of the children to fit-content. Doing so will make these elements take up only as much horizontal space as they need and is available within the parent.
You can also set width to max-content but this will ignore the width of the parent and content will extend as far as any descendants need and possibly overflow the parent.
Example:
Problem setup:
.parent {
width: 15rem;
height: 5rem;
border: 1px solid blue;
}
.child {
border: 1px solid red;
}
<div class="parent">
<div class="child">
Content for child
</div>
</div>
Solution:
.parent {
width: 15rem;
height: 5rem;
border: 1px solid blue;
}
.child {
width: fit-content;
border: 1px solid red;
}
<div class="parent">
<div class="child">
Content for child
</div>
</div>
Support for fit-content is pretty good (caniuse?). There's support for fit-content on pretty much all the major desktop browsers (except IE), and unknown support on some of the mobile browsers.
If you truly want the parent div to collapse around its child elements (for whatever reason, based on what you're trying to accomplish) and you then want to center that div, then #Vector's answer is spot on, use display: table with margin: 0 auto.
If it's ok for the div to remain expanded to the full width of the container in which you're trying to center your children, then you have at least a couple more options, again depending on your particular situation.
You can use text-align: center.
.content {
text-align: center;
border-style: solid;
border-width: thin;
}
.content span {
display: inline;
border-style: solid;
border-width: thin;
}
<div class="content">
<div>Test</div>
<div>Test</div>
</div>
You could also use the newer display: flex with justify-content: center, depending on the level of browser compatibility you're supporting, of course.
.content {
display: flex;
justify-content: center;
border-style: solid;
border-width: thin;
}
.content div {
border-style: solid;
border-width: thin;
}
<div class="content">
<div>Test</div>
<div>Test</div>
</div>
have you tried using display: inline-block? DIV will take up 100% width because they are block elements.
If you modify DOM adding extra html elements inside a div and that cause it to be expanded, a simple solution would be to add that css to the root element of those extra html elements:
max-width: fit-content;
That will prevent them to expand the parent div's width.

How can I horizontally centre (center) an element of unknown width when another element is floated next to it?

Given the following HTML:
<div id="container">
<div id="left">Left</div>
<div id="centre">Centred</div>
</div>
and CSS:
#left {
float: left;
text-align: left;
}
#centre {
text-align: center;
}
How can I horizontally centre the centre element without giving it a fixed width? The following image shows the desired result:
Here's what I can get it to look like so far:
Here's a jsFiddle demonstrating what I have done so far.
I prefer a general-purpose solution that doesn't require widths of anything to be specified.
If you know the width of the left div, you can do it like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
#left {
float: left;
width: 30px;
}
#centre {
margin: 0 40px;
text-align: center;
}
#left, #centre, #container {
border: 1px solid #000;
}
#container {
width: 175px;
padding: 5px;
}
</style>
</head>
<body>
<div id="container">
<div id="left">Left</div>
<div id="centre">Centred</div>
</div>
</body>
</html>
If you want the #centre element with a shrink-to-fit width for the content, you can use the following:
<div id="container">
<div id="left">Left</div>
<div id="centre">Centred</div>
</div>
and the following CSS:
#container {
width: 175px;
text-align: center;
position: relative;
border: 1px solid black;
padding: 5px;
margin: 5px;
}
#left {
position: absolute;
border: 1px solid black;
padding: 5px;
margin: 5px;
}
#centre {
display: inline-block;
border: 1px solid black;
padding: 5px;
margin: 5px;
}
If you want to get the shrink-to-fit width for #centre, you need to either float the element, use absolute positioning or declare an inline-block display type. Since you don't want to specify a width for #centre, using float or absolute positioning will not allow you to center the content. However, if you specify display: inline-block and use text-align: center on the parent #container, you will get center the element and have some styling control for the border, padding and so on.
However, for this to work, you must use absolute positioning for the #left element. If you use float, the content of #centre will wrap around the left element and change the centering.
Set position: relative on the #container otherwise the #element will be positioned with respect to the root (or some other non-static positioned) element of the page.
Fiddle: http://jsfiddle.net/audetwebdesign/hTFBa/
Footnote
In your demo example, you have single word text labels for the content. If you had multi-word phrases, you would need to constrain the left element's width or specify some margins on the center element to prevent text overlap.

Floated div - fill available width

I have to divs floated, one is on the left, the other on the right. What i want to do (without js) is that the right div fills the available space (width: 100%). The problem is, that the left div has an dynamic width, else I could simply use margin-left.
I also tried display: table-cell; but that won't allow me to use margin, only border-spacing.
Any suggestion?
You can probably do it like this, works in IE8 and better, in FF, in Safari. You could use padding instead of margin, as in this example:
<style>
.c_0 {
display: table;
width: 100%;
border: 4px solid orange;
}
.c_1 {
display: table-cell;
width: 20%;
border: 1px solid red;
padding-right: 20px;
}
.c_2 {
display: table-cell;
border: 1px solid blue;
}
</style>
<div class="c_0">
<div class="c_1">
has a width and padding instead of margin
</div>
<div class="c_2">
has the rest
</div>
</div>
EDIT
This only works with "%" on the first row. I saw it too late, that you want pixels.