css stretch li based on content - html

I have this code here and I am trying to make the ul.submenu li to stretch according to its contents. As you can see, the 3rd li of the ul.submenu has a long text which hides instead of stretching the li.
I have tried changing the display property of all elements on the DOM with various combinations but I cannot get it right.
What am I doing wrong and why this happens? What am I missing?
Any help will be very much appreciated! :)

Currently the text has little bearing on the layout, because of block display and absolute positioning.
You can change this by giving the lis display: inline-block and white-space: nowrap. I've forked an example where the sub-menu is as long as the longest item requires.
Explanation
inline-block gives the element properties of inline and block display: inline in that the element should flow like text, and take its initial layout and dimensions from the text it contains. But the block part means you can also specify top and bottom padding and margin, clears, etc. Even with this set, the containing element is still absolutely positioned (most text content just flows as long as it needs because normally the containing block element fills 100% width - not the case for absolute, relative and fixed elements), so its instinct is to collapse to the minimum width, that of the first word. But if we use white-space: nowrap, we can force the text to extend as much as it needs, so the full sentence is used as the measure.

You could just change the min-width to:
min-width: 240px;
View Example

Related

Do fixed and absolutely positioned elements not take the full width of their container like block elements? If yes then why?

From this post I came to know that absolutely positioned elements do not behave as block level elements.
"Because absolutely positioned elements do not behave as block level elements and do not flow after each other like normal adoes."
From the discussion in comments it seems that absolutely positioned elements are still block-level elements. The only difference is that they do not take the full width of their parent container. I figured out that the same is true for fixed positioned elements too. I tried the following code. In this code two boxes are shown. One is statically positioned and second is absolutely positioned. It can be seen that statically positioned box takes the full width of it's parent container(viewport). But the absolutely positioned box doesn't take the full width of it's parent container(viewport).
<!DOCTYPE html>
<html>
<style>
.abslnowidth {
position: absolute;
display: block;
border: 1px dotted black;
padding: 10px;
background-color: gray;
}
.staticyeswidth {
position: static;
background-color: bisque;
padding: 15px;
border: 1px dotted black;
}
.abslnowidth:hover, .staticyeswidth:hover {
color:red; background-color: yellow;
}
body {
text-align:center;
border: 2px solid darkgreen;
}
</style>
<body style="">
<p>Two boxes are shown below, viz, the gray and bisque colored boxes. The gray colored box is absolutely poistioned and the bisque colored box is statically positioned <br></p>
<div class="abslnowidth">
Absolutely positioned
</div>
<div class="staticyeswidth">
Statically positioned
</div>
</body>
</html>
Note that the the fixed positioned box behaves similar to absolutely positioned box in that that it also doesn't take the full width of it's parent container.
Much to my surprise, I noticed the fixed/absolutely position element doesn't behave like block-level elements even if I explicitly set display: block; It kind of behaves like inline or inline-block elements, as inline or inline-block elements do not take the full width of their parent container.
Precise Question:
Are absolutely/fixed positioned elements still block-level elements?
Do fixed and absolutely positioned elements not take the full width of their container like block elements are supposed to take? If yes then why? If it is defined this way for some specific purpose then what is that purpose. Please note that I'm not asking for unilateral opinion. I mean if someone really knows why this feature exists and what would be the practical downsides, had it been not this way. Or in other words,
Would there be technical downsides to the web-design if the absolutely/fixed positioned boxes were made to take the full width of their container. My guess is that absolutely/fixed positioned block are supposed to be adjusted. E.g. see this code used to make tool-tip. The black tooltip section should not take the whole width of "Hover over me" box because then we'd have to manually set the width of tool tip box. So I think that's a good reason to define absolutely/fixed positioned boxes to not take the width of their container.
Please provide some good reference e.g. w3 official documentation if possible.
This question could have different possible answers depending on what kind of block behavior you're expecting or referring to.
As per your comment above, the following answer refers to the width behaviour of such element.
Normally, block-level elements per default take up the full available width of their container element. However, when you set position: fixed or absolute the element isn't displayed in the same sense as with the rest of the elements.
As per MDN:
A block-level element occupies the entire space of its parent element (container), thereby creating a "block."
As such, the meaning of the container for a block-level element makes alters when refering to absolute or fixed positioned elements. It makes more sense to rather call it the parent.
Since there is no container element to inherit its width, you're seeing it behave more like an inline-block-type element.
Here's what the W3C says for calculating the width of an absolutely positioned, non-replaced element:
The constraint that determines the used values for these elements is:
left + margin-left + border-left-width + padding-left + width + padding-right + border-right-width + margin-right + right = width of containing block.
If all three of left, width, and right are auto: First set any auto values for margin-left and margin-right to 0. Then, if the direction property of the element establishing the static-position containing block is ltr set left to the static position and apply rule number three below;
This is true. You have not defined any values for width, left nor right nor do they inherit such values. As such they take the default auto. The direction property is indeed ltr as well, so we continue on to rule number three as suggested, which says:
width and right are auto and left is not auto, then the width is shrink-to-fit . Then solve for right.
The shrink-to-fit width rule applies, and goes as follows:
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, calculate the available width: this is found by solving for width after setting left (in case 1) or right (in case 3) to 0.
Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).

Why the second div moves to another line even if both of them are set to display:inline-block?

I'm a bit afraid of using floats as I didn't yet understand clearing the floats and all the hacks that are on the internet in regard to that activity so I've used display:inline-block to place two divs in inline fashion. Their container has a
width:auto;
max-width:900px;
and each of the divs has
display:inline-block;
width: 450px;
Now no matter what I do the second div always breaks to another line right below the first div.
Here's the code : http://codepen.io/anon/pen/xgtFd
I have already modified the width of the two divs like for example
width:440px;
but it didn't help. Still the second div is slightly 'off place'. That's weird cause I was making a website and using pretty much the same approach for my header like in this project. Please help me determine the problem.
I would be glad for any help.
The widths are too wide.
Bump the nav down to about 446px, and they come back in line.
Why 444px instead of 450px? Two reasons:
Your border is taking 2px.
There is whitespace between the <div> tags in your markup, which is reflected in the rendering. If you would like it to be able to make it 450px, put the closing div tag and the next opening div tag immediately adjacent, like so: </div><div id="nav">
If you want to be able to keep the border, and set the width to 450px, then you should check out box-sizing, and utilize box-sizing: border-box;.
Edit:
To address your vertical alignment issues, you need to apply vertical-align: top; to the div elements (the nav and logo divs).
And, the ul isn't centered because when you apply display:block to it, it fills the full width. So you could either make the contents of the div centered with text-align: center on the ul, or you could make the ul display: inline-block.

alignment of a div

What is the default behaviour of a div?
I noticed that even if a put a width for a div let's say 100px,
if i put a 2nd div with the same width will put it on the second line.so by default doesn't matter the width. it puts it on different lines?
in this case i understand the need of float.
I thought that any element i put in a html page,they will be side by side unless i add a break element or paragraph or something with that role.
Or maybe i do not use it correctly the div for this kind of alignment,but i really want to
clarify this for good.
A div element is, by default, display: block.
This value causes an element to generate a block box.
The rendering of them is described here
Block-level elements are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the 'display' property make an element block-level: 'block', 'list-item', and 'table'.
Block-level boxes are boxes that participate in a block formatting context.
and then here
In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block.
To stop this kind of rendering, you can use float to cause block level elements to bubble up beside each other. You can also modify the display property of the div.
Divs are block-level elements which mean they stack...like blocks. Although it sounds reasonable that since the width would allow them to fit side-by-side without a float, this is not how they are designed to behave.
If an element is an inline element as opposed to a block, its behavior is to fit side-by-side. You can force this behavior on a div if you would like by tying the two ideas together. You can do something like:
<div style="display:inline-block"></div>
This will allow the div to maintain its other block properties but allow it to fit inline as text and images would and, if this the your desired goal, avoid the use of float.
The DIV by default takes 100% of the screen, even if you set it width the space on the right cannot be occupied by anything.
Try this:
The way to have two div on the same line would be to make them float:
<div style = 'float:left;width:500px;background-color:red;color:white;'>Hey</div>
<div style = 'float:left;width:100px;'> There</div>

Width auto is not working when hover

I'm creating a web application where I need to do some design tweaks. Please check this one http://jsfiddle.net/rkumarnirmal/5w3FG/9/
When I hover, it shows the border in gray. What I need is I want to fit the border box to fit the width of the text. I tried to set the width:auto but still its not working, showing the border box to the page width size.
How can I do it?
Thanks!
Set text-preview to inline-block:
#text-preview {
display:inline-block;
zoom:1; /* if you need IE7 support */
}
Inline-block will cause the element to render as if inline rather than occupying all of the available horizontal space, but will lets you set inner dimensions and padding as a block element would.
Note that IE7 doesn't support inline-block unless you force the hasLayout property. The easiest way to do that is with zoom:1;.
width:auto on a div translates to width:100% because a div is a block level element.
If you want to have it size to the text you'll need to either use a more appropriate inline tag like a span or depending on the semantic meaning of the data, a definition list (dl).
You can also change the display property of your wrapper div to be inline or inline-block but that is not semantically correct.

How Input Div Span elements respond to a float element placed above it?

We took a 300px wide div, in that we had a 100px wide label tag and had it float:left and immediately after that we took three scenarios. We placed:
an input with width:400px
a div with width:400px
a span with small text and large text
You can see how they are rendering here: http://realution.in/htmlcss/practise/repost.html
Can anyone explain why they are rendering so differently?
Also is <input> a block or inline element?
They render so differently because you set different css properties and use different elements in every example. Also adding the float to label but not to any other elements, and not giving any other elements the css clear property creates this rendering issue.
A proper explenation of floats is done on A List Apart
Inline: An inline element only takes up as much width as necessary, and does not force line breaks.
Block: A block element is an element that takes up the full width available, and has a line break before and after it.
from w3schools
The label element is a inline element. Adding the float: left removes it from the document flow and makes it a block element. The explicit display:block isnt necessary.
Most properties you use on a span element are useless unless you set it to display: block, float: left or display: inline-block. Right now the set height, width and margin are ignored. If you want to adjust the size of the span you can only use: line-height and padding
Both the label and input are inline elements. The input takes up a newline because it will never be able to fit next to anything. The size of the input is larger then its parent.
The css display: block doesnt really do much for a label in this case. Because it has a float and no other element does. In a good browser, you should not see any difference between the label with or without display:block except for the last example where the label will actually be on the left against instead of floating against the previous label
The div is displayed ontop of the label. This is because with the float: left the label is outside of the normal document flow. The div element is ontop of it, because the div is inside the normal document flow.
The text inside the div is next to the label and not ontop of it, because text has a default inline display. If you would remove the text from the label the text inside the div would align on the left.
Adding a clear: left to the div would restore the normal document flow, putting the div on a new line
The label both float left and the span is displayed after them. The width: 300px; on the span doesnt really do anything on inline elements. If you want it to have a width you should either float it, give it a display: block or display: inline-block
The height of the pink area is determined only by the span because this is the only element inside the document flow. adding overflow:hidden to the parent div or a empty div with clear:both after the last label will both fix the box to go around all elements inside it.
The labels still both float on the left, only this time the inline span is so big the email label cant float left of it, so it is positioned next to email but lower, where there is room. The room is there because the span is only 15 pixels high while the label is 20px high, this is for both elements determined by the line-height property