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.
Related
I have the following:
#innerLabels,
#innerFields {
display: inline-block;
width: 200px;
height: 200px;
border-style: solid;
border-width: 1px;
vertical-align: top;
}
.innerLabel {
display: table;
border-style: solid;
border-width: 1px;
height: 100px;
width: 80%;
}
.innerLabel div {
display: table-cell;
vertical-align: middle;
border-style: solid;
border-width: 1px;
}
#outterFields {
background-color: red;
width: 60%;
min-width: 300px;
height: 300px;
}
#outterFields div {
display: inline-block;
}
<div id="outterFields">
<div id="innerLabels">
<div class="innerLabel">
<div>hello</div>
</div>
</div>
</div>
I can't work out why the inner most div isn't being centred? I did look at some of the answers here regarding centring however I can't see what the problem is...
I want the hello to be centred vertically to the centre but not horizontally. All other divs are positioned how I want them. There is no error in the other divs they are positioned side by side for a reason. The only change I want is the hello div moved vertically to the centre
You are just overiding your inner div with
#outterFields div {
display: inline-block;
}
Just remove it or if you where intending a direct child do:
#outterFields > div {
display: inline-block;
}
#innerLabels,
#innerFields {
display: inline-block;
width: 200px;
height: 200px;
border-style: solid;
border-width: 1px;
vertical-align: top;
}
.innerLabel {
display: table;
border-style: solid;
border-width: 1px;
height: 100px;
width: 80%;
}
.innerLabel div {
display: table-cell;
vertical-align: middle;
border-style: solid;
border-width: 1px;
}
#outterFields {
background-color: red;
width: 60%;
min-width: 300px;
height: 300px;
}
#outterFields div {
/* display: inline-block; */
}
<div id="outterFields">
<div id="innerLabels">
<div class="innerLabel">
<div>hello</div>
</div>
</div>
</div>
Your outterfields display inline block is overwriting other display items. I came up with better solution for you. I haven't used table but used flex here learn about flex it's more worth.
#outterFields {
background-color:red;
width:60%;
min-width:300px;
height:300px;
}
#innerLabels, #innerFields {
display:flex;
align-items:center;
width:200px;
height:200px;
border: 1px solid #000;
}
.innerLabel {
display:flex;
align-items:center;
border: 1px solid #000;
height:100px;
width:80%;
}
.innerLabel div {
display:table-cell;
vertical-align: middle;
border: 1px solid #000;
}
<div id="outterFields">
<div id="innerLabels">
<div class="innerLabel"><div>hello</div></div>
</div>
</div>
The necessary and most often sufficient condition where you can center a div using a display: table-cell, is as follows:
<div id="a">
<div id="b">
<div id="c">Helo</div>
</div>
</div>
CSS as follows:
body, html {
height: 100%;
}
#a {
display: table;
width: 100%;
height: 100%;
}
#b {
display: table-cell;
vertical-align: middle;
}
#c {
margin: auto;
text-align: center;
}
You need html and body elements to actually span the entire height of the document area if you want your a div to be able to make use of its 100% height. If your use case demands height that does not depend on the height of the document body, you don't have to use the body, html selector.
When you use display: table the otherwise auto-expanding width for a div element (width: auto implicit rule) does not apply the same way anymore as elements with display: table use a conservative width calculation -- they only by default take as much space as the content requires. Since I am illustrating a "100% 100%" centering to you, I have width: 100% there to have the element expand to available parent width.
height: 100% is likewise needed to have the element expand to available parent height. It does not matter if its display: block as with regular div elements, or display: table -- you need to specify height if you want computed height that goes beyond content height.
The display: table-cell rule only works if there is an ancestor element with display: table, hence you need at least two elements inside one another to apply display: table-cell to the one that is contained in the other. You don't need to specify height because elements with display: table-cell occupy available parent height automatically.
vertical-align rule for the display: table-cell elements is the only case where the alignment applies to the content inside the element, as opposed to its usual behavior where it applies with regard to how the element is positioned within the parent. Meaning that in our case, the vertical-align tells the browser that everything contained in the element with display: table-cell is to be centered vertically within its computed height.
For the c element you would need margin: auto only if you had content that did not completely fill available parent width. Since div elements normally do, it is not necessary, but is forward thinking on my part -- in case you decide to use span or something else that computes its width conservatively. The text-align speaks for itself -- The anonymous textual content and text inside descendant elements, will be centered in the middle along horizontal axis.
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.
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
I have the following fiddle for this question: http://jsfiddle.net/jcb9xm44/
There are 2 inline-block div's in a parent div:
<div class="outer">
<div class="inner1">
Y
</div>
<div class="inner2">
X
</div>
</div>
The css assigns a width to the parent div and 2 widths to the child div's.
.outer {
width: 210px;
border: 1px solid red;
}
.inner1 {
width: 200px;
border: 1px solid orange;
display: inline-block;
}
.inner2 {
width: 50px;
position:relative;
left: -50x;
display: inline-block;
border: 1px solid lightblue;}
I was expecting that both divs appear on the same line. Although the parent is not wide enough to hold both children, since the second child has a negative offset, it should be possible to fit them both on the same line. Why does it break the line?
Why does it break the line?
As you stated, it's because the parent element isn't wide enough for both elements. To change this behavior, you could add white-space: nowrap to the parent element in order to prevent the inline-block elements from wrapping.
Example Here
.outer {
width: 210px;
border: 1px solid red;
position:relative;
white-space: nowrap;
}
Side notes:
You had a typo - left: -50x -> left: -50px.
inline elements respect whitespace in the markup.
The element's border is included in its width calculations. Use box-sizing: border-box to include it.
You could alternatively use margin-left: -50px as Mary Melody pointed out.
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.