Float block element without specifying width - html

I am reading the book Head First HTML and CSS and there it is written that a requirement for any floating element is that it must have a width. I tried floating right a div element without specifying width on it, and the float property works(it moves the div furthest right as possible) as supposed. Does this mean that there is an error in the book, or it is something that i am missing ?

Yes, you can have floated elements with no width values declared in the cascade. Then, through a defaulting process, the specified value will be the initial value.
For width, the initial value is auto.
CSS explains what should happen when a floated non-replaced element has width: auto:
If width is computed as auto, the used value is the
"shrink-to-fit" width.
Calculation of the shrink-to-fit width is similar to calculating the
width of a table cell using the automatic table layout algorithm.
Roughly: calculate the preferred width by formatting the content
without breaking lines other than where explicit line breaks occur,
and also calculate the preferred minimum width, e.g., by trying all
possible line breaks. CSS 2.1 does not define the exact algorithm.
Thirdly, find the available width: in this case, this is the width of
the containing block minus the used values of margin-left,
border-left-width, padding-left, padding-right,
border-right-width, margin-right, and the widths of any relevant
scroll bars.
Then the shrink-to-fit width is:
min(max(preferred minimum width, available width), preferred width)
The "shrink-to-fit" algorithm is now called fit-content measure.

float:right is simple stacking of elements, left to right until a line width is filled, then top to bottom. Like writing an English newspaper page.
float:left is used for things like a sidebar, it would take up the whole page, unless its width is constrained. This is why the width must be specified.

Related

Why does a percentage margin cause a new line?

<div style = "float : left; background-color: #dd3fb8;">
<a style = "margin-left : 10%;">a</a>
<a>b</a>
<a>c</a>
</div>
In the example above, the letter "c" would be on new line, but if I set "margin-left" to px unit, "c" would be on the same line as "a" and "b". Why does this happen?
Unfortunately, the CSS2.1 spec doesn't appear to have a clear answer to this. In fact, I would say this is well within the realm of undefined behavior.
Here are the relevant points I can find:
Floats without a specified width will shrink to fit their contents. In the case of floats with only inline content, the float needs to be made just wide enough to fit its contents on a single line (notwithstanding explicit line breaks) and no more.
Percentage margins are calculated based on the width of the containing block.
Note that it says:
If the containing block's width depends on this element, then the resulting layout is undefined in CSS 2.1.
... but as far as I can see, the behavior is consistent across all browsers.
That being said, the reason this statement applies is because since the margin of the inline element falls within the content bounds of the float, it can be said that the width of the float (the containing block of the inline elements) depends on the this element (the element having the margin).
Here's what I can deduce based on the points above:
When the margin is specified as a percentage, the width of the float is calculated without taking the margin into account, because it's not possible to calculate the margin until the width of the float has been determined.
The margin is then calculated based on the used width of the float, and the letter "c" wraps to a new line as a result of being pushed forward by the margin on "a". The width of the float does not change.
Again, none of this behavior is specified at all, and so technically it's not in violation of the spec. However, it seems sensible.
When the margin is specified as a pixel value, the margin is calculated first. The width of the float is then calculated taking this margin into account (remember that horizontal margins do apply to inline elements as normal). Per the shrink-to-fit algorithm, this is the preferred width: just wide enough to contain all the inline elements on a single line.
Unlike with percentage margins, this is very clear-cut, as implementations should have no trouble calculating computing absolute values for margins first.
I would be hard-pressed to call this a bug in any of the browsers, especially since they all behave consistently.
Lastly, of course, you can avoid this undefined behavior entirely simply by giving your floats explicit widths where possible. It does help to understand why you should do so, however.
Since your div is floated, and its width is auto (implicitly), http://www.w3.org/TR/CSS21/visudet.html#float-width applies:
If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.
“shrink-to-fit” width basically means, let the element be as wide as its content requires it to be.
Now without the margin-left, that is no problem: All three of your a elements are inline elements that contain a specific character each – easy enough to determine their individual widths, and add them up.
But now you want a margin-left in percent, and here things get complicated – if we look at the definition for margin-left, it says:
Percentages: refer to width of containing block
Now, that leaves us in a bit of a pickle, since the width of the containing block (which is established by the floated div element), is computed based on its content – but now this margin-left would change the overall width of that content, but is in itself dependent on the width of the containing block, which it itself influences …
That’s a classical problem of two measurements that are dependent on each other … and that is therefor basically unsolveable.
http://www.w3.org/TR/CSS21/box.html#margin-properties says,
 The percentage is calculated with respect to the width of the generated box's containing block. […]
If the containing block's width depends on this element, then the resulting layout is undefined in CSS 2.1.
Edit: Basically the same as what BoltClock said in his answer, just took me a little longer …
The link has a left margin of 10%, 10% of how much? The parent element is floated left which means it does not have a width of its own, instead it expands as much as its contents. If you try to imitate how the browser would compute the resulting box and you will find yourself in a fix:
Let the width of the content (and therefore the container) be 30px
Add 10% of 30px = 3px left margin to the link
The resulting width of the container is 30 + 3 = 33px
This creates a loop where margin increases as outer width is increased and outer width increases as the margin is increased (10% of 33px = 3.3px means container width changes from 33px to 33.3px and so forth). For such computations the resulting behavior is undefined (as pointed out by CBroe).
The browser seems to avoid the loop and sticks with the 30px width. The 3px margin introduced after calculation causes the third link to flow into second row. The browser again avoids the loop by sticking with 30px width.

Should I always explicitly set width on floated items?

Here and there I see suggestions that I should always set width on floated items. But when I'm exploring CSS of popular web-services (such as Twitter/Google), I see that almost nobody does that.
Is it still considered good style to always set width on floated items? In which cases should I set 'width' property and when it can be safely omitted?
Some quotes:
SmashingMagazine says that:
“You should always set a width on floated items (except if applied directly to an image – which has implicit width). If no width is set, the results can be unpredictable.”
HTML and CSS: Design and Build Websites book says:
When you use the float property, you should also use the width property to indicate how wide the floated element should be. If you do not, results can be inconsistent but the box is likely to take up the full width of the containing element (just like it would in normal flow).
Well it really depends on the browser, you must check the results in multiple browsers to be sure that none of them "misunderstood" your settings. I'd set a width anyway, because no browser can misunderstood that.
Block element takes the full width of the parent. If you use float it will not take the full width, the width would be how much the element width it is.
i use width with floating elements in percentage of the containing div , the only problem you get is that the containing div might not wrap arround its content , so you have to put on the main div overflow:auto

Vertical size height of inline-block to max without wrapper block

>My sample code at jsfiddle<
I want to justify the height of blocks in same lines, i.e. visual margin must be the same.
Which way we can do that?
If it's possible, I want to make width of blocks to 100% ONLY if it's sinle block in line (if container block's width < 2*min-width of children blocks). The second wish describes why I wantn't to use wrapper)
Any ideas?
oops, corrected link!

Why does CSS padding increase size of element?

I am trying to give my div and textarea some padding. When I do this, it increases the size of the element, instead of shrinking the content area inside of it. Is there any way to achieve what I am trying to do?
You could add box-sizing:border-box to the container element, to be able to specify a width and height that don't vary when you add padding and/or border to the element.
See here (MDN) for specifications.
Update (copied comment to answer)
Right now, the value border-box is supported in all major browsers, according to MDN Specs
Some browsers of course requires proper prefix i.e. -webkit and -moz as you can clearly see here
According to CSS2 specs, the rendered width of a box type element is equal to the sum of its width, left/right border and left/right padding (left/right margin comes into play as well). If your box has a width of '100%' and also has margin, border and padding, they will affect (increase) the width occupied by the object.
So, if your textarea needs to be 100% wide, assign values to width, margin-left/right, border-left/right and padding-left/right in such a way that their sum equals 100%.
In CSS3 we have three box-sizing models. You can use border-box model:
The specified width and height (and respective min/max properties) on
this element determine the border box of the element. That is, any
padding or border specified on the element is laid out and drawn
inside this specified width and height. The content width and height
are calculated by subtracting the border and padding widths of the
respective sides from the specified ‘width’ and ‘height’ properties.
This was a mess on W3C part and various browsers only added to this complexity with their own versions of box models. Personally, instead of thinking which browser or CSS setting will do the trick I just wrap the box' content in yet another DIV statement and use margins on that DIV, instead of using padding, like this:
<div id="container" style="width: 300px; border: 10px solid red;">
<div id="content" style="width: 250px; margin: 25px;">
Some content
</div>
</div>
Although this only works for fixed size containers
It depends on the browser and it's implementation of the box model. What you are experiencing is the correct behavior.
IE traditionally got it wrong: http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug
For a more cross-browser solution, you can avoid this behavior, by wrapping whatever tag that needs padding into another tag with fixed width, and giving it width:auto. This way, if the parent has a width of x, and you add padding to the child, the child will inherit the full width of x, applying the padding correctly without modifying the parent width or its own.
A div by default takes the width of its parent container, so to avoid browser compatibility issues, you could add a child div in the specified div then add the required padding to the child div.
N.B - don't specify width to the child div because it would increase if you add padding

Child spans of the same width

I am trying to create a horizontal menu with the elements represented by <span>'s. The menu itself (parent <div>) has a fixed width, but the elements number is always different.
I would like to have child <span>'s of the same width, independently of how many of them are there.
What I've done so far: added a float: left; style for every span and specified its percentage width (percents are more or less fine, as the server knows at the time of the page generation, how many menu items are there and could divide 100% by this number). This works, except for the case when we have a division remainder (like for 3 elements), in this case I have a one-pixel hole to the right of the parent <div>, and if I rounding the percents up, the last menu element is wrapped. I also don't really like style generation on the fly, but if there's no other solution, it's fine.
What else could I try?
It seems like this is a very common problem, however googling for "child elements of the same width" didn't help.
You might try a table with a fixed table layout. It should calculate the column widths without concerning itself with the cell contents.
table.ClassName {
table-layout: fixed
}
If you have a fixed width container, then you are losing some of the effectiveness of a percentage width child span.
For your case of 33% you could add a class to the first and every 4th child span to set the correct width as necessary.
<div>
<span class="first-in-row">/<span><span></span><span></span><span class="first-in-row"><span></span><span></span>...
</div>
where
.first-in-row { width:auto; /* or */ width:XXX px; }
have you tried the decimal values, like setting width to 33.33%?
As specified in the CSS syntax, the width property (http://www.w3.org/TR/CSS21/visudet.html#the-width-property) can be given as <percentage> (http://www.w3.org/TR/CSS21/syndata.html#value-def-percentage), which is stated to be a <number>.
As said at the number definition (http://www.w3.org/TR/CSS21/syndata.html#value-def-number), there some value types that must be integers, and are stated as <integer>, and the others are real numbers, stated as <number>. The percentage is defined as <number>, not as <integer> so it might work.
It will depend on the browser's ability to solve this situation if it can't divide the parent's box by 3 without remaining, will it draw a 1- or 2-pixel space, or make 1 or 2 spans out of three wider than the rest.
In reference to Xian's answer, there's also the :first-child pseudo-element. Rather than having first-in-row class, you'd have this.
span:first-child {
width: auto;
}
Obviously, this is only applicable to a single line menu.