Why does display:block not stretch buttons or input elements - html

I'm trying to understand the reason behind this problem:
What's the underlying reason behind <button> or <input> elements not behaving like other elements when set to display:block!
I'm not looking for workarounds to fix this problem, so please don't point me to this answer because it doesn't answer the question.
Here's a js-fiddle that illustrates the problem
Update 1: #Pete is correct, the default size attribute of an element is what sets the size even on block, as you can in this fiddle the size and cols attribute of <input> and <textarea> changes their width. That solves part of my question.
With that in mind, my question is now, why is the <button> element not behaving like other block elements? It's a mystery to me!

Button, Input and other form elements are actually replaced elements - see this answer: HTML5: Non-replaced vs. replaced element?
Additionally, button and input are inline elements. Thus, reading the MDN docs regarding visual formatting here: https://developer.mozilla.org/en-US/docs/Web/CSS/Visual_formatting_model, as well as the w3c docs here: https://www.w3.org/TR/CSS21/visudet.html#inline-replaced-width, you can conclude that for replaced inline elements:
If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'.
Therefore, button and input have an intrinsic width set to their content (or the size attribute on input, if used). That's why just specifying display: block doesn't do anything to the size of a button or input. You also have to override the intrinsic width of the elements.
Update: While researching more after answering this question, I found a much older answer which goes into much more detail about this same issue. You can find it here: https://stackoverflow.com/a/27605483/630170.

I think that a default value is assigned to the size attribute of inputs which means unless you specifically override it, your width won't be 100%
If you look at the firefox specification and scroll down to the section about size, you can see that they have a default value of 20
I'm not sure about the properties for the button that cause that not to be 100% width when changed to block

Some elements like <input>, <textarea> or <button> have default styles included, like their border or, in your example, their size. I think the reason is, that HTML has still to be usable with the simplest markup and does not require any styling from css (or inlined attributes) to work.
The fact that display: block does not change this behaviour is, that an input field already is a block element. But in contrast to most other elements it does have a default value on the width attribute which is not 0.
The reason I think is pretty simple: If you create an <input> field and use no css or styling, you simply wouldn't see it, like you do not see an unstyled <div>.

Related

How is the width of an <svg> determined when margins are involved?

It seems like the width of an <svg> element is set based on the size of the parent, but ignoring margins:
Why is this? And how can I make an <svg> behave like any other block element when it comes to sizing?
Fiddle: http://jsfiddle.net/4p3ww/
There is no way for some SVG content to say it wants to take up whatever space is available after borders, padding and margins have taken their share (there is no way to create SVG that does NOT have an intrinsic width/height since the 'width' and 'height' attributes default to 100%).
https://wiki.mozilla.org/SVG:Sizing
Seems like there is still a debate on how different browsers should render these, so I'd be careful. Even with height/width attributes and max-width CSS, it still rendered pretty weird for me.
http://jsfiddle.net/4p3ww/3/
Just don't use <svg> and <img> as if they were block elements. They are not (Is <img> element block level or inline level?).
If you wrap your <svg> into a <div> with the contained class as per your example, you get results more in line with what you'd expect: http://jsfiddle.net/gLndw/

Is CSS3 box-flex working as intended in this example?

I was writing the layout of an app using the box-flex property (in Chrome) and I have found a strange behaviour, in my opinion, that I am wondering if might be a bug or that I just ignore the reason for those workings.
The code looks like this: http://jsfiddle.net/5tuCh/
There is a weird "div" resize when resizing the "textarea" so that the dimension of the "div" minus the "textarea" is equal to the dimension of the second "div", in order to satisfy "box-flex:1.0" I guess. Now if the reason for box-flex was making it easier to arrange the layout, this behaviour makes it unusable in this case.
Might it be that I am missing something?
Thanks.
This is in fact correct behaviour. From MDN:
The containing box allocates the available extra space in proportion
to the flex value of each of the content elements.
In your example, div.text boxes actually render with a height, meaning that any space beyond that would be spread evenly (or, rather, according to the flex ratio) between the elements. Setting height:0 on these elements would force behavior that I believe you're after (fiddle: http://jsfiddle.net/5tuCh/16/); I also had to remove the height:100% declaration on your textarea to prevent it from collapsing inside an element with zero height. I'd speculate that you may accomplish the textarea to take up full height of the parent element by setting its box-flex property as well.
Update:
OP's having issues with textarea behaviour could possibly be addressed by the following style:
textarea {
position:absolute;
top:10px;right:10px;bottom:10px;left:10px;
resize:none;
}​
The parent element, of course, has to have position:relative set, which would result in the textarea taking up all available space in the container (w/10px spacing between the borders). Not sure if that's what you were after though. Fiddle: http://jsfiddle.net/5tuCh/36/

Valid to specify width for form tag - either inline or through css?

I just need to know if we can specify with for form tag or we need to put it in a container and give width to that parent element of form tag??
Which approach is valid??
To the best of my knowledge, a form element behaves a lot like a div in most situations, and so will accept a width, but usually this is just an implied 'auto'.
According to the Default stylesheet ( http://www.w3.org/TR/CSS2/sample.html ), form naturally is applied display:block, which leads me to believe you can treat it just like any other block element.

CSS - Why am I not able to set height and width of <a href> elements?

I'm trying to create css buttons by using the following html markup:
Forgot password
But it ends up being not bigger than the text in the middle. Even though I've set the class's height and width.
You can preview the problem here btw, www.matkalenderen.no
Notice the first button, that's a form button and it's using it's own class. At first I tried to use the same class on the css button as well and the same problem appeared, so I tried to separate them into their own classes. In case there was some kind of crash. But it didn't matter anyway.
What am I missing here?
As the others have said, by default <a> is an inline element, and inline elements can't specify a width or height. You can change it to be a block element like this:
a {
display: block;
}
Though it will then display (unsurprisingly) as a block, sitting on its own, outside the flow of the surrounding text. A better solution is to use display: inline-block which might be a best-of-both-worlds solution depending on your situation.
See PPK's writeup about it.
The real use of this value is when you want to give an inline element a width. In some circumstances some browsers don't allow a width on a real inline element, but if you switch to display: inline-block you are allowed to set a width.
Because <a>'s are inline elements by default. In CSS define a { display:block; } and height and width settings will be applied.
Of course, you may not want to declare all anchor tags as block level elements, so filter by class or id as needed.
I think the most proper solution is display: inline-block; which will allow you to set height for the element that still will be treated as inline element.

pesky HTML layout: how do I hide an element while preserving the layout?

I want to hide a form input field. But calling setVisible('inputID', false) causes my liquid layout to collapse. I don't want that.
Is there some easy workaround here? I thought about trying to render the input field's foreground color, background color, and border color to be all white. But that's getting unnecessarily complicated.
There are two ways of hiding elements using css:
Settings the display attribute to none
Setting the visibility attribute to hidden
The first option removes the element from the flow, while the second option hides the element but still lets it take up space in the flow.
You are using the first option and you want to use the second option instead.
Example:
document.getElementById('inputID').style.visiblity = 'hidden';
If you set an element's "visibility" style to "hidden" it will hide the element from view but it will not affect the layout of other elements.
It's hard to give better advice without seeing your code, but there's a few things you can do:
Given that you're using JavaScript, you could get the width and height of the form input you're removing, create a new div with those dimensions, inject it after the form element, then hide the form element. A bit of a hack, but it works.
Surround your input with a div in your HTML and give it an explicit width and/or height in your CSS. Then remove the input with JavaScript as you're doing already.
That's the definition of an element with relative positioning.
Just give it relative positioning and coordinates far off the screen.
e.g.
position:relative
left:-2000px
It should put the element out of the screen, but leave a "hole" where it would have been.