I'm trying to create html buttons/labels with text and initially zero width (after insertion, they'll be stretched to be visible, but I want this transition to be smooth). I've tried modifying the initial width and min-width style properties, but no luck.
The following is what I want to work.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.zerowidth{width: 0px;min-width: 0px;}
.nonzerowidth{font-size: 30px;}
button{font-size: 30px;}
label{font-size: 30px;}
span{font-size: 0px;}
</style>
</head>
<body>
<span>
<button>This should be visible</button>
<button class='zerowidth'>I want this to be invisible</button>
<label class='zerowidth'>same here</label>
<button>c</button>
</span>
</body>
</html>
I want the above to appear identical to a version without the .zerowidth elements, such that the .zerowidth elements can have their widths animated to nonzero values later.
If there's an easier way to insert an item into the DOM that allows for smooth repositioning of the elements around it (the above is a toy example - in practice I'll be inserting elements programatically from Dart), I'd be happy to hear that too (though I'd rather stay away from absolutely positioning everything if possible).
Thanks.
To make a button element really zero-width as regards to total width occupied (not just content width, which is what the CSS property width specifies), you need to set horizontal padding and vertical borders to zero. Moreover, to prevent browsers from dividing the content into several lines, you need to prevent line breaks. And you need to make overflowing content hidden; for an element with zero content width, any content overflows, of course. You would thus add the following:
.zerowidth {
padding-left: 0; padding-right: 0;
border-left-width: 0; border-right-width: 0;
white-space: nowrap;
overflow: hidden;
}
For some reason, this is not sufficient for making a label element zero-width (tested on IE, Chrome, Firefox). On the other hand, a label element is for specifying labels of form fields and other labellable elements, and you get nothing but trouble by trying to use it for other content. So consider using e.g. span instead.
<button class='zerowidth'>I want this to be invisible</button>
<label class='zerowidth'>same here</label>
if you want these two things invisible, why not add style="display:none;" to both. And if you want to display them, do a hover effect and display:block; to that element.
Related
This is a common problem but I can't figure out why it happens.
I have a parent div and inside that div I have 3 divs with width set to 33% (exactly, not 33.3%!) and display: inline-block.
In Chrome it works well, but in Mozilla and Opera it does not (I didn't test it in IE yet). I thought the problem might be in the algorithm browsers use to calculate pixel sizing from percentages. But when I checked the DOM metrics, I found that the parent's width is 864px and the child's is 285px (that's correct: 864 * .33 = 285.12). But why doesn't it fit in the parent? 285 * 3 = 855, that's 9px less than parent's width!
Oh, yes, padding, margin and border for all divs set to 0 and DOM metrics confirm that.
Whitespace in the HTML source code
In the HTML source code, When you have lines of text or images, or elements that are inline-block, if there is any whitespace between them (blank spaces, tabs, or new lines), a single blank space character will be added between them when the page is rendered. For example, in the following HTML, a blank space will appear between each of the four pieces of content:
one
two
<img src="three.png"/>
<span style="display: inline-block;">four<span>
This is very helpful for lines of text, and for small images or HTML elements that appear inside a line of text. But it becomes a problem when inline-block is used for layout purposes, rather than as way to add content inside a paragraph of text.
Removing the extra space
The safest, cross-browser way to avoid the extra 4px or so of space that's added between inline-block elements, is to remove any whitespace in the HTML source code between the HTML tags.
For instance, if you have a ul with 3 floated li tags:
<-- No space, tabs, or line breaks between </li> and <li> -->
<ul>
<li>...</li><li>...</li><li>...</li>
</ul>
Unfortunately, this hurts the maintainability of the website. Besides making the code unreadable, it severely compromises the separation of data and formatting.
If another programmer comes along later and decides to put each li tag on a separate line in the source code (unaware of why the tags were on the same line, or possibly running it through HTML Tidy and not even having a chance to notice any related HTML comments), suddenly the website has a formatting bug that may be difficult to identify.
Consider floating elements instead
The whitespace behavior strongly suggests that it may be inappropriate to use inline-block for general-layout purposes, to use it for anything other than adding content inside the flow of a paragraph of text.
Plus, in some cases inline-block content is very difficult to fully style and align, especially on older browsers.
Quick summary of other solutions
Put the close tag on the same line as the next open tag, with no white space between them.
Use HTML comments to fill all of the whitespace between the close tag and the next open tag (as #Arbel suggested).
Add a negative left margin to each element (usually -3px or -4px, based on the font-size). I don't recommend this particular approach.
Set the font-size for the container element to 0 or 0.01em. This doesn't work in Safari 5 (not sure about later versions), and it may interfere with Responsive Design websites, or any website that uses a font-size unit other than px.
Remove whitespace-only text nodes from the container using JavaScript or jQuery. This doesn't work in IE8 and earlier, as text nodes are not created in those browsers when there's only whitespace between elements, though space is still added between the elements.
Set letter-spacing and word-spacing for the container (as #PhillipWills suggested). Further info. This requires standardizing em sizes on the website, which may not be a reasonable option for all websites.
Add text-space-collapse: discard; to the container (previously called white-space-collapse). Unfortunately, this CSS3 style is not yet supported by any browsers, and the standard hasn't been fully defined.
If you don't want to mess up the HTML formatting e.g. having all the elements with inline-block written in one line for future readability and also get rid of the extra white space that is added between them, you can "comment" the white space.
For example in your code this will solve the problem, it will even work with 33.3% instead of 33%:
.parent {
width: 100%;
}
.child{
display: inline-block;
width: 33.3%;
}
/\
<div class="parent">
<div class="child">bla-bla1</div><!--
--><div class="child">bla-bla2</div><!--
--><div class="child">bla-bla3</div>
</div>
A space is added between the inner divs. There is some CSS voodoo to correct this problem:
div {
letter-spacing: -.31em;
word-spacing: -.43em;
}
div div {
letter-spacing: normal;
word-spacing: normal;
}
Of course, you'll probably prefer to use classes or something to differentiate between parent and children.
Add float:left;
.parent{
width: 100%
}
.child{
float:left;
display: inline-block;
width: 33%
}
http://jsfiddle.net/H6Whc/1/
Has anyone tried display: table? If that's not a good idea, why not? This works in all modern browsers and I tested it down to IE9.
.parent{
display: table;
width: 100%;
}
.containers {
box-sizing: border-box;
border: 1px solid #000;
height: 50px;
width: 33.3%;
display: table-cell;
}
This is a mentioned by a number of comments and by #Avin, but removing display: inline-block and replacing it with float: left works.
.parent{
width: 100%
}
.child{
float:left;
width: 33%
}
This is a common problem, but it can be sorted out very easily by assigning the display: table CSS property to the parent div.
I am attempting to make a div element work similarly to that of an input element.
http://jsfiddle.net/MRP5M/6/
I was wondering how the input element achieves the ability to scroll to the side without having scrollbars? I don't want my div element expanding to multiple rows to hold content, but I did not see any CSS properties controlling this behavior on the input element.
UPDATE: All good solutions. Thank you guys for looking into it. It would appear that some aspects of the input element are controlled by the browser (i.e. highlight-to-scroll). It would appear difficult to emulate this functionality without use of Javascript. I've marked the first response as the solution.
Here's the answer: http://jsfiddle.net/MRP5M/12/
There's is one caveat: I'm not sure how to disallow new lines....
You can set "white-space: nowrap;" inside your .editable div
After that, just set a fixed height to your #wrapper (something like 20px) and overflow: hidden;
It will work as I just tried.
The "white-space: nowrap" will avoid any line break, so you don't need to set a fixed width inside your .editable div.
Update: As for the option to select all text with your mouse, Alohci just pointed out on the comments to this post that you can add "overflow: auto;" to your .editable div and it will behave as wanted, at least on Chrome, where I just tried. Alohci also pointed to a Fiddle. Credits to him.
Input fields aspect and behaviour is controlled by the browser itself. You can use CSS to prevent the text from breaking:
See this working Fiddle example!
.editable {
white-space: nowrap;
}
As to scroll without using scroll-bars, you can only achieve either by using JavaScript or altering the HTML as to have an input disguised as a div:
See this working Fiddle example!
HTML
<div id="wrapper">
<input type="text" value="A really long string of content" />
</div>
<input type="text" value="A really long string of content" />
CSS
#wrapper{
width: 151px;
}
#wrapper > input {
border: 0 none;
background-color: white,
color: black;
}
I have a Silverlight video player that I want to display in a "100% browser width/height" mode (i.e. not fullscreen, but filling up the entire browser display area).
Regular player: http://play.nimbushd.com/lfu53b5
Fullscreen version: http://play.nimbushd.com/lfu53b5/fullscreen
I have tried nearly every node in the DOM and set width/height to 100%, with margin: 0px, padding: 0px. Seems to work great in Firefox. Why, then, does IE display a vertical scrollbar with a little whitespace at the bottom?
Edit: Since this issue is fixed, the short explanation: A 100% height/width Silverlight control within an ASP.NET <form> tag spills over just a bit in IE because of the form tag.
This behavior is caused by inline elements within the <form> - inline elements always render a line-height worth of pixels. Any of the following CSS rules will fix it:
form { font-size: 0; }
or
form * { display: block; }
Alternatively, you could try to get rid of all inline descendants of <form> (this includes text nodes) - but I'm not sure it would actually work (not tested). Plus it would render your markup hard to maintain (you'd need to strip all newlines and such... could be done during deployment, but I think this is taking it too far).
You need this this styling in you html:
<style type="text/css">
html, body {
height: 100%;
overflow: hidden;
}
body {margin: 0px}
</style>
Note that this applies a style to both html and body to enforce the height of html element to the viewport height and therefore also the body.
I am trying to create a liquid 3 column area within a list item. To achieve this, I use the standard method of having 3 elements, of which the first two are the sides, floated left and right, and the 3rd is the content, which should sit between the two. The following HTML works fine in Firefox, but doesn't render correctly in IE7 - the content is rendered below the two floated elements. Any ideas what the problem is?
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
*
{
margin: 0;
padding: 0;
border: 0;
}
span
{
display:block;
}
.corner
{
width: 12px;
height: 12px;
}
.tl
{
float: left;
}
.tr
{
float: right;
}
.fill
{
margin: 0px 12px;
}
</style>
</head>
<body>
<ul>
<li>
<span class="tl corner">a</span>
<span class="tr corner">b</span>
<span class="fill">text text text</span>
</li>
</ul>
</body>
</html>
Note that replacing the spans with divs results in the same effect. I've also tried various DocTypes with no luck. And it works fine outside of the list, hence the problem appears to be intrinsic to using the list.
The way IE sees it, you're trying to jam in the lines one after the other, but the first two have already taken up their space, FLOATing away, which leaves the last SPAN in the LI to fight for the next level, which in IE looks like the next level below.
Since the last SPAN is not floated, that's also why it gets knocked to the next level.
Also, SPANs are inline styles, not block level elements. You should replace SPAN with DIV is you still want to try and style this in a LI element.
You should also use a full DOCTYPE so the browsers will know how to render the page. Otherwise they will default to quirks mode, ugly and all over the place.
But the better tactic is to create this float of 3 columns outside of the LI and in a DIV setting.
Have a read of CSSplay or Max Design on creating 3 column layouts.
It's a bit difficult to say anything without seeing the markup, but why don't you just put the two elements which should float inside the content element? You would have to adjust with some padding on the content element, but that should do the job. Then again, not quite sure what you mean. If you supply us with a bit more markup, it would be easier to tell.
The center block should have margins to either side allowing room for the floated blocks.
The answer is to wrap the spans in a block level element (say, a div), with overflow set to hidden. Example came from a more in depth look at the 2nd CSSplay example.
In the following HTML, I'd like the frame around the image to be snug -- not to stretch out and take up all the available width in the parent container. I know there are a couple of ways to do this (including horrible things like manually setting its width to a particular number of pixels), but what is the right way?
Edit: One answer suggests I turn off "display:block" -- but this causes the rendering to look malformed in every browser I've tested it in. Is there a way to get a nice-looking rendering with "display:block" off?
Edit: If I add "float: left" to the pictureframe and "clear:both" to the P tag, it looks great. But I don't always want these frames floated to the left. Is there a more direct way to accomplish whatever "float" is doing?
.pictureframe {
display: block;
margin: 5px;
padding: 5px;
border: solid brown 2px;
background-color: #ffeecc;
}
#foo {
border: solid blue 2px;
float: left;
}
img {
display: block;
}
<div id="foo">
<span class="pictureframe">
<img alt=''
src="http://stackoverflow.com/favicon.ico" />
</span>
<p>
Why is the beige rectangle so wide?
</p>
</div>
The right way is to use:
.pictureframe {
display: inline-block;
}
Edit: Floating the element also produces the same effect, this is because floating elements use the same shrink-to-fit algorithm for determining the width.
The beige rectangle is so wide because you have display: block on the span, turning an inline element into a block element. A block element is supposed to take up all available width, an inline element does not. Try removing the display: block from the css.
Adding "float:left" to the span.pictureFrame selector fixes the problem as that's what "float:left" does :) Apart from everything else floating an element to the left will make it occupy only the space required by its contents. Any following block elements (the "p" for example) will float around the "floated" element. If you "clear" the float of the "p" it would follow the normal document flow thus going below span.pictureFrame. In fact you need "clear:left" as the element has been "float:left"-ed.
For a more formal explanation you can check the CSS spec although it is beyond most people's comprehension.
Yes
display:inline-block is your friend.
Also have a look at: display:-moz-inline-block and display:-moz-inline-box.
The only way I've been able to do picture frames reliably across browsers is to set the width dynamically. Here is an example using jQuery:
$(window).load(function(){
$('img').wrap('<div class="pictureFrame"></div>');
$('div.pictureFrame').each(function(i) {
$(this).width($('*:first', this).width());
});
});
This will work even if you don't know the image dimensions ahead of time, because it waits for the images to load (note we're using $(window).load rather than the more common $(document).ready) before adding the picture frame. It's a bit ugly, but it works.
Here is the pictureFrame CSS for this example:
.pictureFrame {
background-color:#FFFFFF;
border:1px solid #CCCCCC;
line-height:0;
padding:5px;
}
I'd love to see a reliable, cross-browser, CSS-only solution to this problem. This solution is something I came up with for a past project after much frustration trying to get it working with only CSS and HTML.