I have a set of <span> elements (each of them is nested to correspondent <div>). They build a stack of panels, like in the picture below.
When span contains some text, it has a normal height. But when it is empty, it's height is 0px. But I need it to have a normal height (to make it look like in the picture).
How to achive this behavior? (I tried to insert a space, but maybe there's a better solution).
Here is a simple and robust solution:
span.item:empty:before {
content: "\200b"; // unicode zero width space character
}
(Update 12/18/2015: rather than using \00a0 non-breaking space, use \200b, which is also a non-breaking space, but with zero width. See my other answer at https://stackoverflow.com/a/29355130/516910)
This CSS selector only selects the spans that are "empty", and injects some content into that empty space, namely a non-breaking space character. So no matter what font size and line-height you have set, everything around that <span> will fall into line, just as if you had text present in that <span>, which is probably what you want.
http://plnkr.co/edit/eXHphA?p=preview
The result looks like this:
I see two problems with using min-height:
it is vulnerable where font sizes change
the text baseline is not in the correct place
Here's what the counter-examples look like when things go wrong:
The font size changes, and now you have to hand tune the min-height again. You can't use the same class to support different parts of your website where font sizes are different. Here the font size in this place is 30, but the min-height is still set to 20. So the empty spans are not as tall. :-(
http://plnkr.co/edit/zeEvca?p=preview
Your empty span has the correct height with min-height, but it doesn't line up correctly with the text surrounding the span. The baseline falls incorrectly. Look at the line that says "Huh?" below:
http://plnkr.co/edit/GGd7mz?p=preview
Code for this last example:
<div class="group">
Hello <span class="item">Text</span>
</div>
<div class="group">
Huh? <span class="item"></span>
</div>
<div class="group">
Yes! <span class="correct"></span>
</div>
css:
.group {
background-color: #f1f1f1;
padding: 5px;
font-size: 20px;
margin-bottom: 20px;
}
.item {
background-color: #d2e3c5;
border-radius: 6px;
padding: 10px;
margin-bottom:5px;
display: inline-block;
min-height: 20px;
}
.correct {
background-color: #d2e3c5;
border-radius: 6px;
padding: 10px;
margin-bottom:5px;
display: inline-block;
}
.correct:empty:before {
content: "\00a0";
}
You could set span display:inline-block; and then add min-height
From the picture, it seems that you have already set display: block on the span elements. If not, add that. Alternatively, consider using div instead. The difference between the two elements is that span is inline by default, div is block by default, so why not use the latter?
Then you need to set min-height to a value that equals the height of items that have content. This is normally determined by their line height. The default line height varies by font (and by browser), so to get consistent results, set the line height explicitly, e.g.
* { line-height: 1.25; }
span { min-height: 1.25em; }
Maybe this will work -
span{
min-height:16px;
}
Related
I can vertically center one-lined text with line-height, but also with padding-top and padding-bottom.
What are the pros and cons of each?
body {
font-size: 12px;
font-family: sans-serif;
}
div {
border: 1px solid #333;
padding-left: 10px;
padding-right: 10px;
display: inline-block;
}
.vcenter1 {
line-height: 50px;
}
.vcenter2 {
padding-top: 19px;
padding-bottom: 19px;
}
<div class="vcenter1">Lorem ipsum line-height...</div>
<div class="vcenter2">Lorem ipsum padding...</div>
For me both of the methods are valid for instances where the line of text is guaranteed to only ever span one line (either by nature of the containers width being fixed or by manipulation of the content and/or CSS white-space property), but it depends on your intention as to which is more appropriate:
If you want the height of the element the text is contained within to be fixed, then using line-height seems most appropriate and maintainable because changes to the size of the font wont impact the height of the container (unless the font becomes taller than the container).
If however the height of the container is not fixed and it's more important that the white-space either side of the font remains, padding is the more appropriate option.
There are of course other ways of centring text vertically within an element, this previous question How do I vertically center text with CSS? has a lot of useful information on the topic.
Purely in terms of vertically centering, it matters not a jot. But note that in the second case, you are padding around a line box whose height is proportional to the font-size. Different browsers use slightly different proportions by default, so the bordered box will be different sizes in different browsers. That won't happen in the first case.
Here is my JsFiddle
When I inspect the size of the anchor tags with Chrome developer tools it shows me 144px*18px for the 1st element and 310px*18px for the 2nd element.
I want to know why it does not take the height and width of the containing element and how it is being calculated.
.gallery {
background-color: #abcdef;
}
.gallery img {
display: inline-block;
margin-left: 20px;
margin-top: 20px;
}
.normal {
height: 160px;
width: 110px;
border: 5px solid black;
}
.wide {
height: 160px;
width: 280px;
border: 5px solid black;
}
<div class="gallery">
<img class="normal" src="">
<img class="wide" src="">
</div>
The CSS 2.1 spec says
The dimensions of the content area of a box — the content width and
content height — depend on several factors: whether the element
generating the box has the 'width' or 'height' property set, whether
the box contains text or other boxes, whether the box is a table, etc.
Box widths and heights are discussed in the chapter on visual
formatting model details.
The <a> element defaults to a display value of inline. Its contents participate in the layout so it is a non-replaced element.
For height, the spec says:
10.6.1 Inline, non-replaced elements
The 'height' property does not apply. The height of the content area
should be based on the font, but this specification does not specify
how.
So 18px is arrived at from a single line of text, taken from the font metrics. Neither the larger image content, nor the containing block size plays any part.
For width, the spec says
10.3.1 Inline, non-replaced elements
The 'width' property does not apply. A computed value of 'auto' for 'margin-left' or 'margin-right' becomes a used value of '0'.
in other words, the width is determined by the <a> element's contents, paddings, borders and margins.
For the first <a> element that's 114px (contents - image plus one space) + 20px (left margin) + 2x5px (left and right border) = 144px
For the second <a> element that's 280px (contents - image) + 20px (left margin) + 2x5px (left and right border) = 310px
Just need to account for the spaces. The elements are being laid out in a line box in a inline context, so the spaces at the start of the first <a> element and at the end of the second <a> element are being dropped. The spaces at the end of the first <a> element and the start of the second <a> element are being collapsed into one space. When spaces are collapsed, it's always the first space which remains, which in this case is the one at the end of first <a> element, so that's why a space participates in the width of the first <a> element but not in the width of the second one.
use display:inline-block in anchor
.gallery a{
display:inline-block;
}
here is updated jsFiddle File
also remove margin from image and add it to anchor
.gallery a{
display: inline-block;
margin-left: 20px;
margin-top: 20px;
}
anchor is always display: inline by default. To make anchor took it's child space, you must give him a display:block, or in this case, display:inline-block so that they will be inlineand block.
a{
display:inline-block;
}
JSFiddle
Read this question for more info.
The a tag's need to be styled as well
I added
.gallery a {
display: inline-block;
}
I had the same issue, for example, I have HTML generated by GitHub flavored markdown, so I can have paragraphs containing anchor with images inside.
Actually setting display: inline-block in anchors did not work for me; I did also set display: block in images. Using Sass nested something it looks like this:
.gallery {
a {
display: inline-block;
img {
display: block;
}
}
}
Instead of applying {display: inline-block} on <a>
, try applying {float: left} on the child of <a>. The height of the <a> would now match the height of the child.
Another solution is to use a negative margin-bottom attribute with the img element (the size depends on the font, so, it's better to be sure of the used font by using an #font rule, 0.2em was fine for the font I use, moreover, using em units is a good idea as the size depends on the font, so, if you change the font-size later, you won't have to change this CSS code):
HTML:
Something, <img src="whatever.png" alt="Whatever" />, something else.
CSS:
a:link {
display: inline-block;
}
img {
margin-bottom: -0.2em;
}
That way, all the texts are well aligned with the image, whatever it's in a link or not, I've done that to have all image + text blocks displayed the same way, but you might use a > img instead of just img in the above code.
By the way, I came up with this solution because I had something like:
a[something]:link::after {
content=" something to add"
}
so, the img {display: block;} was not an option for me as the “ something to add” would have been under the image and the rest of the text after, this would have cut the reading flow.
This is the HTML:
<div>
<p>
We bring you the latest in entertainment & information services, right on your phone. From the latest of Bollywood to the futuristic applications, get it all here!
View All
</p>
</div>
And this is the CSS....
div{width: 350px;}
a{
padding: 30px;
background: red;
margin: 20px;
border-radius: 12px;
background: red;
color: #fff;
font: bold 12px Arial, Helvetica, sans-serif;
text-decoration: none;
}
I know this could be solved by using display: inline-block; in .a. But I would like to know why this is overlapping the text? Should it not to go beyond the text?
DEMO1
DEMO2 now a is within a block level of p.
And also have a look at this DEMO. Img is also an inline element. And why this is not overlapping, this should also be overlapping, right?
<a> tag is inline level but while <img> tag is both inline and block level specially inline-block. So <a> tag is overlapping because of inline level which is corresponding to the text but <img> tag won't overlap because it is behaving inline-block. And you may know the difference between them.
Reference: Is <img> element block level or inline level?
An inline element could not be set its width and height and even doesn't work correctly the margin behaviour what actually should do. The margin is applied only to left or right side. Actually this is why, inline element here <a> tag would not set its width and height and remain in same line and seems to be overlapped when applied padding values.
The following picture makes you clear to understand about inline vs inline-block
View Live Demo
It's overlapping because the default behavior for an <a> tag is to fit with the text. If you want it to behave like a block, then set display: block.
The initial value for the display property on a link is display: inline. This means that it will try to fit in with the text and will accept horizontal margins, and padding on all sides, which is exactly why your link overlaps the text. In order for it to accept vertical margins (so it doesn't overlap), you need to set it to display:block or inline-block if you want it to align with the text still.
Padding doesn't work well with inline elements.
Ref:Inline Elements and Padding
This actually is explained in the W3C spec, although it was a bit tricky to find.
Horizontal margins, borders, and padding are respected between these boxes.
This tacitly implies that vertical margins/borders/padding are not respected. It goes on to say:
The height of a line box is determined by the rules given in the section on line height calculations
If you move the <a> into the contents of the box
We bring you the latest in entertainment View All
You can see this effect: http://jsfiddle.net/rHCNb/7/ -- the horizontal padding is respected, but not the vertical. The fact that it covers the other text has to do with z-indexing.
Add the below property in a.
position:relative;
float:left;
Working DEMO
TIPS:
Write background-color instead of the shorthand background when you
are not associating any other property.
If you write display:block then the block width will be equal to the parent
width, so always write width with display.
a{
padding: 30px;
background-color: red;
margin: 20px;
border-radius: 12px;
color: #fff;
font: bold 12px Arial, Helvetica, sans-serif;
text-decoration: none;
display: block;
width: 50px;
}
DEMO
I've got some inline text marked-up as a span. I've given the span a bottom dashed border (to differentiate it from a hyperlink), but the distance between the span content and the border is a bit too much. Is there a way to reduce it?
I've tried zeroing/negativing (totally should be a word) the margins/paddings as well as reducing the line-height for the element with no luck. Granted, reducing the line-height for an inline span probably shouldn't work.
CSS
body {
margin: 10px;
}
span.test {
color: orange;
border-bottom: 1px dashed orange;
}
jsFiddle
I've managed to do it with a combination of using display: inline-block; and line-height: 1em;
Of course, if you need it less than that, reduce the line height.
http://jsfiddle.net/JxmEu/1/
Change the display of .test to inline-block. Then, you can alter its line-height. Reducing the line-height will move the border up without affecting the font size or text around it.
http://jsfiddle.net/ExplosionPIlls/JxmEu/2/
Given a solitary <li /> I need to increase it's size. Font-size works only in firefox, IE just shows it as same size.
Can I change the LI size another way, or set it's image? Please note (and I know this is bad) there is no UL element, it is invalid markup as it is part of an older system which the design means the UL can't be added in easily.
<li> elements are inline elements so they will get the inner elements' width. You can set display property to "inline-block" and set a width. I guess it will solve your problem.
<li> is an inline element, you can use display: inline-block; to have it accept width, height, background, positioning and other rules, while maintaining its inline flow.
Also you could try using <span> with an image of a dot positioned to the left of the text instead of invalid markup.
.liSpan
{
display: inline-block;
background-image: images/dot.png;
background.position: left;
padding-left: 25px;
}
Or something similar :)
Try adjusting the line-height, or it's padding to increase the height.
.liSpan
{
line-height: 2em;
padding: 1em 0;
}