Break h2 element's background - html

I have an h2 element inside a div. The div is 150px wide but the h2 might be wider, so the text must break and go to the next line. The problem is that even that the text breaks, the background-color of the h2 element doesn't, and thus the h2 element's background color covers the entire div.
Is there a way I could make the h2's background-color appear only under the text?
Example: http://codepen.io/anon/pen/azBOLO
HTML:
<div>
<h2>This is a long text test</h2>
</div>
CSS:
div {
background-color: green;
width: 150px;
height: 150px;
padding-top: 15px;
}
h2 {
background-color: red;
}

Set the h2 to display:inline and line-height to 1em to ensure each line nests with the previous one without gaps.
div {
background-color: green;
width: 150px;
height: 150px;
padding-top: 15px;
}
h2 {
background-color: red;
display: inline;
line-height: 1em;
}
<div>
<h2>This is a long text test</h2>
</div>

I finally made it using this trick: http://css-tricks.com/multi-line-padded-text/
EDIT: As suggested, the trick is to set a padding-left on the div, and then create a ::after class on the span that will fill the empty space on the left (same background color, no text).
That way you can achieve padding on a multiline span

Related

Why Padding right and left does not affect the border of h1?

I'm struggling with this problem:enter image description here
I want the border padding of my header to be 1px left and right but although i put that in css file the border still takes all the screen horizontally...
I want my border to fit the text,not be expanded in that way.Thx if you can help.This is the html for h1:<h1 title="they kidnapped me">Doing some testing here</h1><hr>
H1 is by default a block element which takes up the whole line. Make it inline and it only takes up what space the text takes.
body {
color: white;
background-color: #192e51;
}
.testing {
border: 1px double white;
border-radius: 100px;
display: inline;
}
.content {
text-align: center;
}
<div class="content">
<h1 class="testing"> Doing some testing here </h1>
</div>

Vertical space of span expands in the containing div when it's set to be an inline-block

I have a span embedded in a div like this :
div {
width: 50px;
height: 50px;
background: red;
line-height: 50px;
}
span {
background: yellow;
}
<div>
<span>text</span>
</div>
It works well. However, if I set the span to be display:inline-block, the background color of the span expands to fill up the vertical space of the div. Why?
Because span by default is an inline element. As soon as it becomes an inline-block`, its height will adjust to the full line-height.
In the following example I created two inline-block spans and left the third one at the default inline. The first inherits the line-height 50px from the container, the second has a defined line-height of 40px, which is less than the line-height of the container and therefore leaves some vertical space above and below. The third again has the inline property (which would be the default if span were not defined as inline-block before) and only covers height of the text itself since it's inline.
http://codepen.io/anon/pen/GjAPqg
<div>
<span>text1 inline-block line-height 50px</span>
<span class="span2">text2 inline-block line-height 40px</span>
<span class="span3">text3 inline</span>
</div>
CSS:
div {
width: 200px;
height: 100px;
background: red;
line-height: 50px;
}
span {
background: yellow;
display: inline-block;
}
.span2 {
background: green;
display: inline-block;
line-height: 40px;
}
.span3 {
background: aqua;
display: inline;
}
Your span will inherit the div's line-height, and will try to adjust its height to it.

Why this trick centers text vertically in dynamic height div (and why it breaks)?

I found this stackoverflow answer very interesting. It works to vertically center text of any length in a div of any height. Basically it uses a empty <span> tag directly in front of the node containing text, and
HTML:
<div>
<span></span><p>This is really really long text but it will be centered vertically.</p>
</div>​
CSS:
div {
background: yellow;
color: red;
width: 200px;
text-align: center; /* horizontally center */
height: 300px; /* any height */
padding: 0 20px
}
div span:first-child {
height: 100%;
vertical-align: middle;
display: inline-block;
}
div p {
margin: 0;
vertical-align: middle;
display: inline-block;
}
Also even more interesting is if you separate closing span tag (</span>) and opening paragraph tag (<p>) on two separate lines, or if you add a whitespace between the two, the trick breaks.
My question is - how does this trick work? How is span helping center the text? And why does it break when a newline/whitespace is added in HTML between closing </span> tag and opening <p> tag?
I have created a fiddle to demonstrate both points: https://jsfiddle.net/axRxE/385/
My question is - how does this trick work? How is span helping center the text?
Since you give the span inline-block property, the span then inherits it's parent height (with height: 100%) - which in you example is a fixed 300px. And since you gave also the same property to the paragraph, those two elements are one next to each other. See an example:
#parent {
height: 300px;
}
span {
height: 100%;
display: inline-block;
/* some width and background-color for demonstration */
width: 5px;
background-color: red;
}
p {
margin: 0;
display: inline-block;
}
<div id="parent">
<span></span>
<p>foobar</p>
</div>
And you also put vertical-align: middle (which works with inline-block) on both of them, which gives them that align (you only need to add that property to the larger one):
#parent {
height: 300px;
}
span {
height: 100%;
display: inline-block;
/* some width and background-color for demonstration */
width: 5px;
background-color: red;
/* added vertical-align */
vertical-align: middle;
}
p {
margin: 0;
display: inline-block;
}
<div id="parent">
<span></span>
<p>foobar</p>
</div>
And why does it break when a newline/whitespace is added in HTML between closing </span> tag and opening <p> tag?
That's simple - when you use inline-block there is always a whitespace issue between them. And since you didn't add some width to the paragraph, it takes all the width it can take, and with that additional width from the whitespace, the paragraph goes below the span.
In your example, your parent has 120px width, the span uses 0px, so the paragraph takes all of the parents width, which is 120px. Now, with the additional whitespace (which is ~ 4px), since she paragraph uses all the width, the whitespace doesn't fit so the paragraph "breaks" - it goes below the span.
Also check:
inline-block element with no text renders differently
Vertical-Align: All You Need To
Know.

Hide text if previous element has elements inside of it

I have the following problem. I have a div inside of which there are 2 elements. First element can have children inside of it. Second element has only text.
I want to display text if only there are no elements inside of the previous element.
Ok, this is hard to understand, so here is a reproducible fiddle. As you see I have 2 boxes (inside of the first element) and text in the second element. So in this way I want the div with text to be hidden. But if I will remove the boxes, the text should appear.
Using javascript there were no problems with this at all (calculate the size of the elements inside of the span and if 0 - show text, not 0 - hide text). The problem is that I am trying to achieve the same with pure HTML and CSS.
Is there a way to do this?
You can fake it;
give the container a fixed height and an hidden overflow;
give the text a min-width of 100% and an inline-block display;
If there is something before it, the text will be pushed down, and hidden:
Running demo
HTML
With squares, Text doesn't show:
<div class="content">
<span>
<div class="box"></div>
<div class="box"></div>
</span>
<div class="content-empty">Text</div>
</div>
Without, it does:
<div class="content">
<span></span>
<div class="content-empty">Text</div>
</div>
CSS
.content {
border: 2px dashed #bbb;
margin-top:20px;
height: 94px; /* new */
overflow: hidden; /* new */
}
.box {
width: 80px;
height: 80px;
border: 2px solid #444;
display: inline-block; /* new */
margin: 5px;
background-color: #eee;
}
.content-empty {
text-align: center;
vertical-align: middle;
line-height: 94px;
font-size: 26pt;
display: inline-block; /* new */
min-width: 100%; /* new */
background: silver;
}
No, it is not possible in CSS to have a selector that would select an element according to whether its sibling has children or not.
You can use css3 for this
.content > span:empty + .content-empty{display: none;}
or
.content > span + .content-empty{display: none;}
Check Jsfiddle Demo

How to stack in-line-block elements

Is it possible to stack in-line-block elements?
I have a DIV which I want the elements inside it (h1 and P) to be centred. So I set the DIV to text-align centre and initally set the H1 and P tag to inline-blocks.respectively.
The idea was to display the two elements (H1 and P) as in-line-block elements so content is centred and a transparent png shows in the background for the length of the text.
But the problem I have is that having elements as inline-blocks means they will appears next to each other (I don't want this to happen), so I set the P tag as block element but it's resulting in the transparent png being as wide.
HTML:
<div id="hero">
<div class="container">
<div class="row">
<div class="span12" id="hero-text">
<h2>Heading line</h2>
<p>Paragraph line goes here</p>
</div>
</div>
</div>
</div>
CSS
#hero {
height: 435px;
width: 100%;
background: url(../img/hero-image.png) 0 0 no-repeat;
background-color: #999;
position: relative;
color: #FFF;
border-bottom: 3px solid #E6E6E6;
}
#hero-text {
position: absolute;
top: 33%;
text-align: center;
}
#hero h2 {
font-size: 4em;
font-style: normal;
line-height: 50px;
padding-top: 10px;
background: url(../img/bg-heading.png) repeat;
display: inline-block;
padding: 10px 20px;
}
#hero p {
font-size: 2em;
line-height: 30px;
display: block;
background: url(../img/bg-heading.png) repeat;
padding: 10px 20px;
}
Any help is appreciated.
This was actually tougher to solve than I originally thought. I could find two options for you. If you don't want to change your markup:
Give both #hero h2 and #hero p display:inline-block, and give them widths so that their combined width is greater than 100%. They both can be width:51%, or one can be wider than the other, just as long as their total is more than the width of the parent. This will cause the p to break to a new line. See http://codepen.io/anon/pen/cjDiH OR
2.If you want their widths to be fluid, I'd add an element in between the h2 and p that is display:block. I added hr, then took away its margin, padding and border to make it not visible other than to cause the line break. See http://codepen.io/anon/pen/AGDti
I see you figured out out to get them to stack like in your screenshot.
Now,
try adding width: auto; to #hero p in your css.