Cannot set pixel width of div using css width attibute - html

I'm trying to set up a div which contains 4 divs. I want to set the width of the container and some of the contained divs to set values but they just seem to take the width of the content.
<html>
<head>
<style>
div {
border: 1px solid #888;
}
.container {
width: 300px;
position: relative;
}
.container div {
display: inline;
}
.div1 {
width: 20px;
overflow: hidden;
}
.div2 {
width: 80px;
overflow: hidden;
}
.div3 {
width: 160px;
overflow: hidden;
}
.div4 {
width: 20px;
overflow: hidden;
position: absolute;
top:0px;
right: 0px;
}
</style>
</head>
<body>
<div class="container">
<div class="div1"><img src="1x1.gif" width="1" height="1"/></div>
<div class="div2"><span>date</span></div>
<div class="div3"><span>text</span></div>
<div class="div4"><span>twistie</span></div>
</div>
</body>
</html>
The result looks like this:
+--+----+----+------------------------+---+
| |date|text| |twi|
+--+----+----+------------------------+---+
Can anyone explain why the left-hand divs are not being set to the required widths?

The reason you can't set the widths is because you are setting display:inline;.
When elements are displayed inline, they cannot have their dimensions specified because the size of the element is determined by the length of the text within it.
By default, <div> tags are set to display:block;. This mode can have its height and width specified, but defaults to being displayed below the preceding block.
There are two ways around this for you:
Use display:block; and float:left; -- This will change the blocks into floating elements, which means that subsequent elements will wrap around them. When used with other blocks, this effectively allows you to line them up. However using float can have other unexpected side-effects, due to the wrap-around effect I described.
Use display:inline-block; -- This is my preferred solution to this question. inline-block is a half-way house mode between block and inline. It allows an element to be treated as inline for the purposes of document flow, but still behave like a block internally, in that it will always be rectanguar and you are able to specify height and width, etc. It does have a few quirks (most notably poor support in IE6), but in general for what you're trying to achieve, it's a much cleaner solution and doesn't have the odd side-effects of float.
Hope that helps.

i think it's because of display:inline style
try this:
<div style='width:100px;overflow:hidden;'>
<div style='float:left;width:20px'></div>
<div style='float:left;width:20px'></div>
<div style='float:left;width:20px'></div>
<div style='clear:both;'></div>
</div>

Change your CSS as follows
.container div {
display: inline-block;
}
When you set the container div to inline, you actively set all of its children to inline as well, you may as well have just been using <span>s.
Here is an example for you to see.
http://jsfiddle.net/Kyle_Sevenoaks/ZwKDb/

.container {
float: left;
width: 300px;
position: relative;
}
.container div {
float: left;
}
Should do the trick. Remove the inline display on the interior divs, and float all the divs left. Then you can specify the widths of the divs and any margins between them.

Related

Third div automatically floating

I can not understand how css works, and it's annoying me. I was trying to do some basic side by side two divs and one div below them.
At first I've learned that I had to give float:left for both side by side divs. For curiosity I did'nt gave float:left for the second side by side div, and I came across this layout:
(source: imge.to)
Then I gave float:left for the second side by side div, and I came across this layout:
(source: imge.to)
Question: I didn't gave float:left for third div but it didn't act like the first screen shot. Why?
css code:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 1000px;
margin-left: auto;
margin-right: auto;
}
.blog-posts {
width: 50%;
background-color: #0000ff;
float: left;
}
.other-posts {
width: 25%;
background-color: #00ff00;
float: left;
}
.author-text {
background-color: #ffff00;
}
html code:
<div class="container">
<div class="blog-posts">dend endje denjde akdlsd gsjgıdg sadsujrg spsadnajd asdnsajdd</div>
<div class="other-posts">extra dummy text</div>
<div class="author-text">author text</div>
</div>
When you use a float, you break the natural box-model behavior of the markup.
Your first floated element has a width of 50%, relative to the parent (1000px) it will take the half of the .container. The second (floated) element will take the next 250px. And here comes the good thing.
The third element, which isn't floated, is also a div, thus a block-level element (so implicitly it will take 100% of the width of its parent). If you set the background-color of your first and second element to a transparent one #0000ff00 and #00ff0000 respectively. You will see your third element is growing behind them.
This is, what I mean with "breaking the box-model". Now, to understand this beter, you could start giving a explicit width to the third element. Let's say: 90%, you will see how the yellow background will reduce itself from the right side.
If you set the width to 50% it will "jump" down, to the second line. It will be even broad as the first element, but two times height. With other words, it will try to fit in the first available space.
To avoid this, in the past, we used the clearfix hack... but since flexbox and css grids are broadly supported, we don't have to rely in floats anymore for this side-by-side layouts.
Float has their own use cases, is not that float sucked, it's just not meant for layout.
For more information on this topic you can check this great article about floats on CSS-Tricks.
Wrap the items you want side by side in another wrapper, then apply flexbox to that wrapper:
.my-flex-wrap {
display: flex;
}
Then remove all the floats. Done.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 1000px;
margin-left: auto;
margin-right: auto;
}
.my-flex-wrap {
display: flex;
}
.blog-posts {
width: 50%;
background-color: #0000ff;
}
.other-posts {
width: 25%;
background-color: #00ff00;
}
.author-text {
background-color: #ffff00;
}
<div class="container">
<div class="my-flex-wrap">
<div class="blog-posts">dend endje denjde akdlsd gsjgıdg sadsujrg spsadnajd asdnsajdd</div>
<div class="other-posts">extra dummy text</div>
</div>
<div class="author-text">author text</div>
</div>

Absolutely positioned div is too wide when padding: %

I have two divs, one position:static and one position:absolute. Despite having the same width and padding values, the absolutely positioned div gets about 17px wider. This only happens when I specify the horizontal padding as a percentage. How do I get these divs to be the same width without removing the % padding?
.foo {
border:2px solid blue;
background: pink;
width: 200px;
padding: 20px 20%;
}
.foo:nth-child(3) {
border-color: red;
position:absolute;
top:96px;
}
<div class="foo"></div>
<div class="foo"></div>
<div class="foo"></div>
I know how to fix this:
body {
width: 100%;
}
I'm just not 100% sure why this is happening. It probably has something to do with the absolute positioned element does not share the same containing element (body vs html) and that is what padding that uses percentages is based off of.
That's because percentages are resolved relatively to the containing block, which varies in the absolute case.
For the in-flow elements, the containing block is established by the body element, which by default has some margin, so it's narrower than the viewport.
For the absolutely positioned element, the containing block is established by the nearest positioned ancestor. Since there isn't any, it's the initial containing block, established by the viewport.
The solution is positioning body so that it establish the containing block for the absolutely positioned element:
body {
position: relative;
}
body {
position: relative; /* Establish the containing block for absolutely positioned descendants */
}
.foo {
border: 2px solid blue;
background: pink;
width: 200px;
padding: 20px 20%;
}
.foo:nth-child(3) {
border-color: red;
position: absolute;
top: 96px;
}
<div class="foo"></div>
<div class="foo"></div>
<div class="foo"></div>
The problem you're facing is in reality a pretty common one: default margin on the body.
By adding margin: 0; for the body, the issue is solved. The reason why padding: 20px 20%; behaves differently for the elements is because the percentage value is based on the width of the parent - for the statically positioned elements, this is reduced by the default margin. However, for the absolutely positioned element, this margin on the body is ignored (html rather than body is treated as its parent, which has no margin) and the 20% will be of a larger number.
This is also why you had to use top:96px; instead of top:88px (40px in padding + 8px in borders) for that absolutely-positioned element - the default margin pushed down the top two elements.
Here's your code, adjusted accordingly:
body {
margin: 0;
}
.foo {
border: 2px solid blue;
background: pink;
width: 200px;
padding: 20px 20%;
}
.foo:nth-child(3) {
border-color: red;
position: absolute;
top: 88px;
}
<div class="foo"></div>
<div class="foo"></div>
<div class="foo"></div>
I know this is an old one, but it shows up in the top spot in google for certain terms, so I thought I'd go ahead and give the correct answer.
Yes, this does have to do with inheriting parent, but not in the way described. Body inherits it's values from the html tag, meaning that the issue isn't with the body tag.
The clue is in the very specific 17 pixels. That is the default width of the scrollbar in chrome.
Looking at the code here, the width was specified in %. Setting the body to
width:100%
margin:0px
padding:0px
will set the body to be the same width as the tag
The tag in turn will be 100% of the AVAILABLE window, which means that if your content generates a scrollbar, that width is now -17 pixels wide.
The sollution is to set either your body or your html tag (yes, you can style that one too) to
width:100vw;
vw doesn't take the scrollbar into account, but instead only displays the windows width.
I hope that makes sense, and that I have managed to help you solve your problem.

How to remove space below empty inline-block div (and why is it there anyway?)

I have the following problem: I am creating an inline-block element (.content) within a wrapper-div (.wrapper). If there is content in the .content-div, everything works just fine. But if I remove the content from the .content-div, a space gets added below the inline-block-div.
I am not sure why this happens and how to fix it correctly. Note that after manually removing all spaces and line-breaks in my code the problem persists, but setting the font-size to 0 helps.
Also, setting vertical-align: top to the .content-div helps. I am not sure why exactly.
Whats the best way of fixing it? Why does this happen?
Fiddle: https://jsfiddle.net/cjqvcvL3/1/
<p>Works fine:</p>
<div class="wrapper">
<div class="content">not empty</div>
</div>
<p>Not so much:</p>
<div class="wrapper">
<div class="content"></div>
</div>
.wrapper {
background-color: red;
margin-bottom: 20px;
/* font-size: 0; *//* this would fix it, but why? (problem persists after manually removing all spaces and breaks) */
}
.content {
display: inline-block;
height: 20px;
width: 200px;
background-color: green;
/* vertical-align: top; *//* this would fix it, but why? */
}
Update
I have put together a new fiddle. This should better illustrate my problem. How do I get rid of the green line below the textarea?
https://jsfiddle.net/cjqvcvL3/7/
<div class="content"><textarea>Some
Content</textarea></div>
.content {
display: inline-block;
background-color: green;
}
This happens because you specifically give width and height to the .content.
Have you considered using the :empty pseudo selector?
.content:empty {
display: none;
}
https://jsfiddle.net/cjqvcvL3/5/
Setting your the content display to block instead of inline-block fixes the problem.
.content {
display: block;
height: 20px;
width: 200px;
background-color: green;
/* vertical-align: top; *//* this fixes it */
}
This explains why setting vertical-align to top fixes the problem as well:
The vertical-align CSS property specifies the vertical alignment of an
inline or table-cell box.
Here is a working example: jsfiddle
To remove the gap, you have to surround the content div with a wrapper with font-size:0.
The reason is exained here: answer
inline-block
This value causes an element to generate an inline-level block container. The inside of an inline-block is formatted as a block box, and the element itself is formatted as an atomic inline-level box.
inline
This value causes an element to generate one or more inline boxes.
The most important part for this topic would be that the element itself get's formatted not just the content. Every inline-block element will be seen as atomic inline box and thus take up space.
.wrapper2 {
background-color: red;
margin-bottom: 20px;
font-size:0;
}

Break letters of second child div

I have one requirement, where I need to apply width to the parent element which is equal to the first child element's width. This can be easily achieved using display: inline-block or float: left to the parent element if it has only one child element. But I have more than two child elements in a div. Something like this:
Fiddle
<div class="main">
<div class="first">first</div>
<div class="value">valuevalue</div>
</div>
Right now, If I apply display: inline-block to the parent element, then it is having the width of the second child element.
To not happen this, I tried break-word, word-break css properties on the second child element but still no use.
What I am trying to get is illustrated in the following screenshot:
Some important points:
width of the parent element should be equal to the first child element.
height of the parent element should be equal to sum of all the child elements.
I don't know the width of the first child element.
(EDIT) The first child element has some fixed width and height. I don't know these values.
I want to do this using just css. css3 is welcome. (I know how to do this using javascript)
You can Achieve this easily with CSS3's new intrinsic and extrinsic width values(min-content in this cas), although, it's not supported on IE, so it's not an viable option but I will just post this as it's interesting that we will be able to do that in the future:
http://jsfiddle.net/S87nE/
HTML:
<div class="main">
<div class="first">first</div>
<div class="value">valuevaluevalue</div>
</div>
CSS:
.main {
background-color: cornflowerblue;
width: -moz-min-content;
width: -webkit-min-content;
width: min-content;
}
.first {
width: 50px; /* I don't know this width */
height: 50px; /* I don't know this height */
background-color: grey;
}
.value{
word-break: break-all;
}
I guess in the worst case you could use this for newer browsers and JS for IE and older versions.
Reference:
http://dev.w3.org/csswg/css-sizing/#width-height-keywords
http://demosthenes.info/blog/662/Design-From-the-Inside-Out-With-CSS-MinContent
Ideally, the layout style for a HTML snippet like:
<div class="main">
<div class="first">first</div>
<div class="value">firstvaluevalue</div>
<div class="value">second value value</div>
<div class="value">third valuevalue</div>
<div class="value">valuevalue on the fourth line</div>
</div>
is achievable using the following CSS:
.main {
display: inline-block;
background-color: cornflowerblue;
position: relative;
width: 50px;
}
.first {
width: 50px; /* I don't know this width */
height: 50px; /* I don't know this height */
background-color: grey;
}
.value {
word-break: break-all;
margin: 1.00em 0;
}
as shown in: http://jsfiddle.net/audetwebdesign/tPjem/
However, I had to set the width of .main to that of the .first element in order to get the word-break property to take effect.
The CSS rendering problem here is that you want the width of the .value siblings to be equal to the unknown width of .first, which cannot be done with CSS alone.
CSS rendering is essentially a one-pass top-to-bottom algorithm which means that parent elements cannot inherit values from child elements (tables have a multi-pass algorithm but this won't help in this case). This may change in future versions of CSS, but for the we need to design according to these limitations.
The JavaScript/jQuery solution is to get the width from .first and apply it to .main and bind that to a window re-size action.
In some ways, this problem seems to make sense if .first contains an image which would have an intrinsic height and width. If this were the case, it might make sense to set the width of .main to a reasonable value and then scale the image in .first to fill the width of the .main block.
Without knowing more about the actual content, it is hard to come up with alternatives.
Look at my latest comment for the Fiddle link. I changed some things in the html too. Did set the value div inside the first div to use it's width and added word-wrap to the value div.
.main {
display: inline-block;
background-color: cornflowerblue;
position: relative;
}
.first {
width: 50px; /* I don't know this width */
position: relative;
background-color: grey;
}
.first p {
margin-bottom: 30px;
margin-top: 0;
}
.value {
max-width: 100%;
word-wrap:break-word;
background-color: cornflowerblue;
}
html:
<div class="main">
<div class="first">
<p>first</p>
<div class="value">valuevalue</div>
</div>
</div>
http://jsfiddle.net/jxw4q/12/
Important
this answer may not be useful for you, but can help other user who have a similar problem.
you can have the same look as you desire, but without really stretching the parent height. by using position:absolute; on the second div.
Notice: if the parent don't really stretch, it causes problems.
for example, content that will come directly after the parent, will be showed after the .first element. causing an overlap.
you still can use this for cases where this is the only content in the page, and you want the second div to adjust his width to the first.
(I don't think that this is your case, but maybe it will help other user who might stumble into that question.)
anyway, I think that your only option is to use a Script.
For those who fall under the use-case I've described, Here's a Working Fiddle
HTML: (no changes here)
<div class="main">
<div class="first">First div set the width</div>
<div class="value">second fiv should wrap if bigger then first</div>
</div>
CSS:
.main
{
display: inline-block;
position: relative;
}
.first
{
background-color: gray;
}
.value
{
position: absolute;
background-color: cornflowerblue; /* moved here */
}
I don't think you will be able to achieve it without a little help of javascript. Imagine the the following markup and css :
<div class="main">
<div class="first content">first</div>
<div class="second content">valuevalue</div>
</div>
and then the following css :
.main{
background-color : red;
display: inline-block;
max-width: 50px;
}
.first{
background-color : blue;
}
.second{
background-color : green;
}
.content{
word-break: break-word;
}
Now all you gotta do is to set the max-width of your .main div to be equal to your first element and add the content class to each element. I suppose you are adding your elements dynamically.
I got the solution!!
HTML
<div class="main">
<div class="first">first</div>
<div class="value">valuevalue</div>
</div>
CSS
.main {
overflow:hidden;
width:1px;
display:table;
background-color: cornflowerblue;
}
.first {
width: 50px; /* I don't know this width */
height: 50px; /* I don't know this height */
background-color: grey;
display: inline-block;
}
.value {
word-break: break-all;
}
Working Fiddle
Related link

How to get 100% height on floated neighboring divs?

​<div id='container'>
<div class='left'></div>
<div class='right'></div>
<div class='clear'></div>
</div>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
Given the simple markup above, which can be seen in action here at jsFiddle, how do you get the floated right div to take up the remaining height of its parent container that doesn't have an explicit height? The parent container's final height is determined by the floated left div.
Typically, I solve this issue through Javascript, and fix the heights after the page has loaded. But, there must be an alternative, standard, and optimal method of how this is handled.
I think this is just an inherent issue of structuring a layout this way, so what is the alternative beyond using a <table>?
Can't be done without explicit height on the parent using floats.
You can however use display: table-; and table-cell which mimics the behavior of tables without actually using them:
#container {
width: 200px;
background-color: green;
display: table;
}
.left {
display: table-cell;
width: 30px;
height: 200px;
background-color: red;
}
.right {
display: table-cell;
height: 100%;
width: 30px;
background-color: blue;
}
This way you don't need the clearing element and the two divs will always take up 100% of the height, as long as it's declared.
http://jsfiddle.net/6XagR/4/
​