width of <h*> element flows 100% always - html

When setting the background color of a <H1> tag(or any <H*> tag) the element spans the length of the body element of the HTML page.
<H1>A</H1>
H1
{
background: #ddd;
}
The following image shows the problem and ideal result
I can get the desired effect by statically setting the width of the <H1> tag in the css like
H1
{
background: #ddd;
width: 10px;
}
The problem with this is that if I have text inside the <H1> tag that is bigger than 10px it will overflow the background.

h1 elements use display: block, which is the correct default behavior. It prevents subsequent content from appearing on the same line, and allows borders and backgrounds to be the (appropriate) full width of the content region.
If you need the element to only take the width of the text, use one of the following methods:
an inner element such as <h1><span>h1</span></h1> so that you can select the inner element to provide the background.
span {
background-color: #CCC;
}
<h1><span>h1</span></h1>
display: inline if you want the heading to be treated as inline text and flow appropriately.
h1 {
background-color: #CCC;
display: inline;
}
<h1>h1</h1>
<!-- here's where this fails -->
<h1>h1 again</h1>
display: inline-block if you want the heading to have the features of a block element (such as being able to set padding, height, and width)
h1 {
background-color: #CCC;
border: 1px solid #000;
display: inline-block;
padding: 2px 3px;
}
<h1>h1</h1>
<!-- here's where this fails -->
<h1>h1 again</h1>
float: left; clear: both; if you want the heading to align to the left, but ignore other floated elements. The issue with this one is that it will no longer collapse margins.
h1 {
background-color: #CCC;
clear: both;
float: left;
}
<h1>h1</h1>
<h1>h1 again</h1>

No need to set the width. Just update the display type from block to inline or inline-block, if needed.
Something like this:
h1.ib {
display: inline-block;
}
Fiddle: http://jsfiddle.net/v3f2obr1/

You can control the layout mode of the elements with the display property.
However, there is a problem: most values that make the box shrink to its content instead of growing to cover the container block are inline-level, e.g. inline-block, inline-table, inline-flex. That means that, if there is other inline content around your headers, they will be displayed in the same line (if they fit).
Probably, you don't want that. Then, you can use display: table:
h1 {
display: table;
background-color: #CCC;
}
Before
<h1>h1</h1>
Middle
<h1>h1 again</h1>
After
The table display is block-level, so the header will be in a different line than surrounding inline content. But unlike block, the contents are layed out using the table layout, so the header will shrink to its content.

Edit: Jack Pattishall and zzzzBov beat me to it.
You don't actually have to set the width. There's a CSS property available for solving your problem. display:inline
An inline element only takes up as much width as necessary.
Just set your heading to this.
h1 {
display: inline;
}

Here's a byte-saving way to do it:
H1 {
display: inline;
background-color: #CCCCCC;
}
<h1>Your Text Here</h1><br>

Related

Why when i specified a width property in my p element the text doesn't flow around the div element? Using floats

Why when I specify a width property in my p element, the text doesn't flow around the div element ?
I know one the solution to this is to have float: left; in my p element too. Just looking for explanation, not finding for solution
div {
width: 200px;
height: 100px;
background-color: green;
opacity: 0.2;
float: left;
}
p {
background-color: yellow;
width:10px;
}
<div></div>
<p>Lorem Ipsum</p>
Block elements don't wrap around floats, their contained line boxes do. But since the width of the p element is less than that of the div element, there's no space for the line boxes of the p element to go beside the div element, so the first opportunity for the line box to be placed is below the div element. So wrapping around is exactly what the line box of the p element is doing.
It's probably a display issue.
You can try to set a display:inline-block to your <p> tag.
But I think to put one aside another you can better use flex-box:
Wrap your two or more elements inside a div or a section, and give this div a property display: flex.
By default, it will align those elements horizontally, and the property align-items: center is to align those elements based on the div's center.
<div id="container">
<div>One</div>
<p>Another</p>
</div>
<style>
#container {
display: flex;
align-items: center;
}
#container div {
/* ... Your previous div style */
margin-right: 15px;
}
</style>

line-height in CSS

I have a bit of clarification regarding line-height in css .I tried the following code:
.red {
line-height: 4.1;
border: solid red;
}
.box {
width: 18em;
display: block;
vertical-align: top;
font-size: 15px;
}
<div class="box red">
<div>Avoid unexpected results by using unit-less line-height</div>
length and percentage line-heights have poor inheritance behaviour ...
</div>
In the example above , I havent used display:inline or display:inline-block ,but still I am able to see the spacing between the text .Why is it?
Also , I have one more clarification : when I apply line-height : 25em; on an inline-block element say <div style="display:inline-block;line-height : 25em;"></div> ,
will the space occupy on top and bottom of this element with respect to its parent or the spacing will occur for the inline elements of its children?
In the example above , I havent used display:inline or
display:inline-block ,but still I am able to see the spacing between
the text .Why is it?
An element inherit line-height from its parent, no matter it is an inline/inline-block/block, but as you can see below, a block element behaves different than an inline, where the block element itself is not affected (no space between the div elements) but its content is.
body {
line-height: 4;
}
div, span {
background: lightblue;
}
div + div, span + span {
background: lightgreen;
line-height: 3;
}
div + div + div {
background: lightgray;
line-height: 2.5;
}
<span>
This is a sample text inside a span element<br>
that has a line break making this come in 2 lines
</span>
<span>
This is a sample text inside a span element
</span>
<div>
This is a sample text inside a div element<br>
that has a line break making this come in 2 lines
</div>
<div>
This is a sample text inside a div element
</div>
<div>
<span>
This is a sample text inside a span element<br>
that has a line break making this come in 2 lines
</span>
<span>
This is a sample text inside a span element
</span>
<div>
When I apply line-height : 25em; on an inline-block element say <div
style="display:inline-block;line-height : 25em;"></div> , will the
space occupy on top and bottom of this element with respect to its
parent or the spacing will occur for the inline elements of its
children?
For its children
div:nth-child(2) {
display: inline-block;
line-height: 4;
background: lightgreen;
}
div:nth-child(1),
div:nth-child(3) {
background: lightblue;
}
<div>
This is a sample text displayed as block
</div>
<div>
This is a sample text displayed as inline-block
</div>
<div>
This is a sample text displayed as block
</div>
Line height gives the line the text is sitting on a height value. Think of it as when writing in a notepad. When changing the line heights, you are changing the distance between the lines regardless of whether the sentence overflows onto the next line.
If you are trying to achieve a gap between sentences, separate them with "p" tags and then add padding and or margin to your tags.
.p { margin: 10px 0; }
.p { padding: 10px 0px; }
Hello i think the problem in not for line height. I think the main problem is -
width:18em;
Be clear about em. Basically em depends on its parents value. Read this carefully. I think your problem will be solved. If you still face problem then use -
width:100%;

How can I easily align an element with "display: inline-block" and "overflow: hidden"?

inline-block elements using overflow: hidden position themselves so their bottom margin is the baseline. From http://www.w3.org/TR/CSS2/visudet.html#leading:
The baseline of an 'inline-block' is the baseline of its
last line box in the normal flow, unless it has either no
in-flow line boxes or if its 'overflow' property has a
computed value other than 'visible', in which case the
baseline is the bottom margin edge.
In practice this means these elements are shifted up unexpectedly; e.g., inside a <td> the element will not be vertically centered. A simpler example:
div {
border: 1px solid red;
text-decoration: underline;
}
.ib {
display: inline-block;
}
.h {
overflow: hidden;
}
<div>
<div class="ib">Visible</div>ABgjh</div><br>
<div>
<div class="ib h">Hidden</div>ABgjh</div>
the div with overflow: hidden doesn't share the same baseline as its surrounding line.
I'm looking for a simple way to make that div align itself as if it was following the normal rules for inline-block elements. Basically I want to write a custom element that "just works" whether its consumer applies a vertical-align style, or places it inside a <td>, etc.
This table has an example where I want the element to vertically center itself but instead it pushes itself up (and the rest of the line down).
This fiddle has more examples showing how different pairings of vertical-align behave unexpectedly when one element is display: inline-block; overflow: hidden.
To be clear, this question is asking whether a <div style="overflow: hidden"> can be wrapped in such a way that it can be treated as a regular inline-block element, positioning itself intelligently, without JS or font-based pixel adjustments. I'd want to be able to apply styling to the final component in order to position or align it as I please, as if it were a regular inline-block element.
I am not sure what browsers you are looking to support but if you wrap your DIV with display: flex; you wont get that vertical offset. You can see it here:
div {
border: 1px solid red;
text-decoration: underline;
}
.ib {
display: inline-block;
}
.h {
overflow: hidden;
}
.flex {
display: flex;
}
<div>
<div class="ib">Visible</div>
ABgjh
</div>
<div class="flex">
<div class="ib h">Hidden</div>
ABgjh
</div>
I normally don't use flexbox because of the lack of browser support but perhaps this is the simple solution you're looking for. Hope that helps.

how to make a div width end when its child elements end instead of taking all the available space?

this might be dumb but I'm kinda new to html and css.
I have..
<div>
<img src="#" alt="img">
<p>Lorem ipsum</p>
</div>
css:
div {
background: blue;
}
div img {
float: left;
}
that makes the div background width take all the available space (to the end of the page), what I want is for the div blue background to end on its child elements ending.
I'm not exactly familiar with the block/inline. but applying inline to the div makes the background disappear, applying block does nothing. so what do I do to achieve what I'm looking for?
By default div elements are displayed as blocks. By default blocks stretch to 100% of their container's width. As you've mentioned, setting them to display as inline will make them stretch to their content's width, however there is a mid-way point between inline and block: inline-block:
div {
display:inline-block;
}
JSFiddle demo.
use an inline-block
div {
background: blue;
display:inline-block
}
div img {
float: left;
}
Try this:
div {
background: blue;
display: inline-block;
}
div img {
float: left;
}

CSS: I can't set width to "auto" always appear 100%

for some reason
the width of the div is 100% and if i set it to auto, nothing changes. tried display: block; and still nothing.
what I have in
index.html
.box {
border: 1px solid #555;
display: block;
width: auto;
}
<head>
<title>project x</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class='box'>This is a box</div>
<div class='box'>This is another box</div>
</body>
I enjoy cracking problems but this one crack me.
Edit
I want the div to take the width of the words. I don't want it to be 100%.
adding to Explosion Pills answer now that its clear what you want, this css should work.
.box {
border: 1px solid #555;
display: inline-block;
float:left;
clear:both;
}
Alternatively, you could place some <br> tags after each <div> block
Width display: block, the elements will always use as much width as is available. It seems like you want to use display: inline-block
http://jsfiddle.net/HpMSU/
width:auto on a DIV expands it to fill it's parent, not to be sized by it's children.
ex: http://jsfiddle.net/nTWvr/
To size a DIV by it's content, there are a few methods: How to make div not larger than its contents?
The following options can change the behavior of width: auto from using the available container width to so called shrink-to-fit algorithm:
Float:left/right
Position: absolute
Display: inline-block
Display: inline-table
Display: table
Display: table-cell
Assuming you need that the blocks to stay in the block formatting context of the normal flow (i.e. to go one after another vertically as usually, just have the width of their content), I suppose that in this case display: table will be the best solution.
use display: inline-block
and add a class
.clear { clear:both;}
place it in between the boxes
so
http://jsfiddle.net/HpMSU/1/
Setting width:auto; is close to the same as setting width:100%; (the only real difference is that they handle margin and padding differently).
Also, div objects are by default block elements, so setting display:block; won't change their behavior.
You said you want the div to take up the width of the words. To do that you can either set display:table-cell (which is not very IE friendly) or you can float the div and it will snap to fit the contents inside.
.box { float:left; }
Make sure to properly clear your float after the div to avoid breaking the layout of contents below it.
.clear { clear:both; height:0px; }
<div class="clear"></div>
I know this question doesn't mention centering the element, but that's what I was looking for when I was directed here.
display: inline-block does its job in terms of width, but doesn't work if you also want to center the block. You can add text-align: center to the parent, but then you would have to override this property for all other elements inside you don't want centered.
div {
border: 1px solid #aaa;
padding: 1rem;
display: inline-block;
margin: 0 auto; // doesn't work with inline-block
}
<div>Content</div>
To handle it properly just for this element you need display: table:
div {
border: 1px solid #aaa;
padding: 1rem;
display: table;
margin: 0 auto;
}
<div>Content</div>
I think you want this result:
<head>
<title>project x</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<span class='box'>This is a box</span>
<span class='box'>This is another box</span>
</body>
.box {
border: 1px solid #555;
}
I just changed div to span! try to use proper HTML tags!