I have the following div
<body>
<span style="border:1px solid red; display:inline-block">
Some text<br />
<hr />
some more text
</span>
</body>
In "normal" web browsers, the width of the div is calculated to fit the text. And the hr is 100% of the div.
But in IE7 the hr causes the div to expand to 100% of the body.
Is there any clever css I need to add somewhere so it behaves correctly in IE7?
Please note, I can't set any fixed width.
In IE6/7, display:inline-block only works on elements that are inline by default (e.g., span). So if you try setting a div to display:inline-block, it won't work in IE6/7.
An inline element will size itself to the width of its content. An inline-block element will do the same by default, if it's not given an explicit width. If the hr is 100% (100% of its parent, which in turn is 100% of the child), then there's a circular definition for the hr width that may not work as expected (100% of what? 100% of itself).
To avoid a circular definition for the width that may not work as expected in some browsers (especially IE6/7), either the container of the hr (div, span, or whatever) should have a defined width (in px, %, or em) or the hr itself should have an explicit width (in px or em). Otherwise, the width is not defined in any identifiable way, and it's left up to the browser to decide what to do by default.
If you can't set any widths, that may rule out using an hr tag. And based on the tests I ran, the options don't look very good for CSS solutions either (without setting a width).
Edit:
I think the only way to do this without setting widths or relying on JavaScript or jQuery, is if it's acceptable to have a horizontal line after every line of text (including any long paragraphs that wrap around to the next line, if there are any). In that case you could add a bg image to the container that contains a horizontal line at increments equal to the line-height of the text, displayed at a vertical offset equal to the line-height so a line doesn't appear at the top of the first line of text.
HTML
<div class="main">
<p>This is the first line.<br/>
This is the second line.<br/>
This is a long line that will wrap around to the next line if the container is not very wide.
</p>
</div>
CSS
.main {
background: url(image.png) repeat-x left 15px;
}
p {
font-size: 12px;
line-height: 15px;
}
jsfiddle demo
The width property of the <hr> tag has been deprecated, so you're styling options are limited on the <hr> tag.
15.3 Rules: the HR element
Index of Attributes
A more modern approach is to use the border property of a <div> instead.
Image rendered by IE 7:
Image rendered by Chrome 19:
jsFiddle Demo
HTML
<body>
<div style="border:1px solid red; float:left;">
<p>
Some text
</p>
<p class="border-top">
some more text
</p>
</div>
</body>
CSS
.border-top{
border-top:#000 1px solid;
padding-top:1em;
}
Note: IE 6 & 7 don't support display:inline-block, so you might need to use float:left instead. The article below compares the use of the aforementioned properties:
CSS display: inline-Block: Why It Rocks, And Why It Sucks
Found a method at a blog. The original one required modernizer.js. I've edited it.
HTML:
<div class="hrdemo"><hr /></div>
CSS:
.hrdemo hr {
display:none
}
However, if your div.hrdemo is inside some floated container; you may have to assign a fixed width for it (for IE7).
Related
I have a issue with a div's height not matching the span's below it:
https://jsfiddle.net/daneren2005/f2bmfkxg/:
<div class="outerDiv" style="line-height: 1.33">
<div class="innerDiv" style="font-size: 68.57px; font-family: libre baskerville;">
<span>Large Text</span>
</div>
</div>
The innerDiv's height is 91 which is correct (68.56 x 1.33 = 91.19). The span's height is 86 though. I have no idea where the height came from. I have a HTML -> SVG converter that mostly works except for in some edge cases like this. I just need to understand where this discrepancy comes from so I can handle it in my calculations.
The issue is that the span element is an inline element. For these instances, change the span to and inline-block display:
span {
display:inline-block;
}
Here's some more reading:
css - inline elements ignoring line-height
Here's the updated fiddle:
https://jsfiddle.net/f2bmfkxg/1/
If you change your div's line-height to 1 you will see that it does not affect span's height.
It happens because inline elements like span take only required amount of space to render them.
In my application I have tags that can be from 5 to 15 characters. By that reason the tags width differ, but the surrounding divs increases with the parents width, not the content.
What should I put in the CSS to make the divs width adapt to the width of it's content?
Thanks in advance!
HTML
<div class="tag">
<a href="#">
<span class="content">Test album</span>
</a>
X
</div>
CSS
div.tag {
background: red;
}
Test case: http://jsfiddle.net/T4XJ3/1/
The <div> element has display:block, so it will always take the full width of their container.
You can make them "flexible" by using display: inline-block (demo).
Is this what you're looking for?
inline-block to the rescue!
div.tag {
background: red;
display: inline-block;
}
From the w3c spec:
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.
In simpler terms this means that outside of your div it acts like a span would (sizes to fit contents, flows inline in content, etc.), and inside of your div it acts like a div normally would (for positioning, sizing, padding, etc.).
So the problem is when you have a block of text, and an image that is slightly too tall that you want to place in-line with the text. For example, a smiley. It will cause the line height of that line of the paragraph to grow, making the block of text look ugly.
I've actually already come up with a solution, but it's messy and I don't like it... If I wrap the smiley in a relatively-positioned div, and give it an absolute position I get the effect that I'm after:
.holder{display:inline-block;position:relative;width:16px}
.holder img{position:absolute;top:-16px}
<span class="holder"><img src="/smiley.gif" height="16" width="16"></span>
But it adds extra markup. Is there any way to achieve this without adding extra HTML elements - a pure CSS solution (no javascript!)
I wonder if I'm missing some application of overflow/vertical-align/float/display etc?
Many thanks!
Depending on the desired image position and whether you have a fixed line-height in pixels you could set a maximum height on your image that equals your line-height and set vertical-align: bottom on the image so it fits exactly into your line.
See this fiddle for an example.
p {
line-height: 18px;
}
p img {
max-height: 18px;
vertical-align: bottom;
}
<p>Some text <img src="/smiley.gif"> more text.</p>
Set the image as a background of a DIV and give the DIV fixed dimensions.
<div class="smiley"></div>
CSS:
.smiley {
float:right; <-- or inline-block if you want.
background-image:url(../smiley.gif);
height:20px;
width:20px;
}
I have an html layout like the following:
<div id="header"></div>
<div id="body"></div>
<div id="footer"></div>
If the header is a fixed width, how can I force it to stretch to match the width of the body - for cases where the body is wider than the header.
First, encapsulate all your divs in a parent div. This sets a boundary to prevent certain divs from outgrowing others and makes the min-width hack a little easier to use.
<div id='container'>
<div id='header'></div>
<div id='body'></div>
<div id='footer'></div>
</div>
Then, in your CSS, use the following min-width hack to make the minimum width directive work across all browsers. The details of how it works are included in the comments. Note that when referring to IE, I mean IE 6-7, I believe IE 8 works like all other browsers.
#header {
min-width:800px; /*minimum width for non-ie browsers, ignored by ie*/
width: 100% !important; /*width will autoexpand as necassary in non-ie browsers*/
width: 800px; /*ie uses width as a min-width by default.*/
/*Also IE ignores !important and instead uses the last directive found*/
}
Now as the body div expands to a size greater than that of the header, the header will expand to match it.
I agree with Ian Elliott, I suspect you do not really need it. Maybe centering will do.
If you do need an instrument that allows header to match width with content that follows, table is that instrument. Table with three one cell rows will produce the layout you want, and it used to be a standard way to layout sites. Are you trying to match some old layout?
I am essentially trying to create a version of the "figure" element (upcoming in HTML5), whereby I have an image with a short description below it.
However, I want to limit the width of this entire element to that of the image, so the text isn't wider than the image (wrapping to multiple lines if necessary).
Basic HTML:
<div class="figure">
<img src="..." alt="..." width="..." height="..." /><br />
A description for the image
</div>
I'm well-versed with CSS but I can't think of any pure CSS solution, without adding a style="width:100px" to the div to match the image width.
Update: After a bit of searching and thinking, the best method seems to be using an inline width on the div. I will keep the width attribute on the image, in case I wish the div to be a bit wider than the image (for example to accomodate a longer caption).
This approach also means I could have two images side-by-side with a caption below. If I have a set of images the same size, I can of course add an extra style to each div.
Thanks to everyone who answered!
This could also be accomplished using 'display: table-caption' for the caption, as follows:
HTML
<div class="wrapper">
<img src="image.jpg" />
<div class="caption">My caption...</div>
</div>
Stylesheet
.wrapper {
display: table;
}
.caption {
display: table-caption;
caption-side: bottom;
}
This block can also be floated left of right of other text. I've tested this in IE8+. Here's a JSBin example: http://jsbin.com/xiyevovelixu/1
For setting the width to match the image automatically you could use
.figure {
display: table;
width: 1px;
}
This makes the div behave like a table (not supported in Internet Explorer). Or you could use a table instead of the div. I don't think there is another way of setting the width automatically.
Edit: The simplest way is to forget about the auto width and set it by hand. If it is really needed you can use JavaScript or a table. In this case the use of a table is not so ugly because you are addressing a limitation of the HTML version. In the case of server-side scripting you could also set the width when generating the page.
Stylesheet
div.figure img,
div.figure div.caption {
width: 100%;
}
div.figure div {
overflow: hidden;
white-space: nowrap;
}
note: to enable wrapping just remove that last css line
HTML
<div class="figure" style="width:150px;">
<img src="logo.png" alt="logo" />
<div class="caption">A description for the image</div>
</div>
I've checked it in Chrome, Firefox and IE7 and it looks good in all three. I realise this has the width on the div and not the img, but at least you only need to set the width in one place. Short of using css-expressions (IE only) I can't see a way of setting the outer divs width to the width of the first child element.
I had the same problem and after reading this decided to use an inline-style on the surrounding element. Seems the better solution over using a table to me.
You can also acheive this using the following solution proposed by Temani Afif in his blog post (All credits to him, I just don't want the solution to be forgotten)
<div class="box">
<img>
<h1>Lorem ipsum dolor ..</h1>
</div>
.box {
display: inline-block;
}
h1 {
width: 0;
min-width: 100%;
}
Make the container inline-block, and makes the h1 (or whatever text tag you use) occupy the space dictated by the sibling element. It's essentially a hack, but it works! No unintended semantic consequences like the table solutions
You could use the display:table solution for all other browsers, and a CSS Behaviour for Internet Explorer.