How to underline whole heading divided into two lines - html

I was trying to underline my whole heading (h1), which is divided into two lines like this:
And I've done it successfully but didn't quite understand the logic behind it, i.e. when I apply this CSS, it didn't work:
CSS:
.main h1 {
font-size: 65px;
text-transform: capitalize;
font-weight: bold;
border-bottom: 5px solid #1A77FF;
}
Whereas, when I added span tag it worked for me
CSS:
.main h1 span {
font-size: 65px;
text-transform: capitalize;
font-weight: bold;
border-bottom: 5px solid #1A77FF;
}
Can anyone please explain this to me? Thanks in advance.

Sure.
Any heading tag (like an h1) is a block level element so any border applies to the block as a whole rather than the text inside.
A span is an inline element and is only as wide as the content (with certain constraints). So the bottom border only applies to the span content even when the line breaks.
Mozilla.org (Understanding the inline box model)
Inline boxes are laid out horizontally in a box called a "line box":
If there isn’t enough horizontal space to fit all elements into a single line (or the line is forcibly broken), another line box is created under the first one. A single inline element may then be split across lines
When an inline box is split across more than one line, it’s still logically a single box. This means that any horizontal padding, border, or margin is only applied to the start of the first line occupied by the box, and the end of the last line.
H1.block {
border-bottom: 3px solid red;
}
H1 SPAN {
border-bottom: 3px solid blue;
}
<h1 class="block">BLOCK FORMAT</h1>
<h1><span>INLINE <br/> FORMAT</span></h1>

<div> is a block level element whereas <span> is an inline element.
When you use <div>, it wraps the text in a complete block as follows. So, border property is applied to that whole block.
And when you use <span>, it wraps the content line by line. So, when border property is added, it is shown under each line.

Related

Margin-bottom of h1 not working [duplicate]

This question already has an answer here:
What is the point of CSS collapsing margins?
(1 answer)
Closed 5 years ago.
The margin-bottom style is not working for <h1> tag as seen in the following image. The margin between heading and anchor tag buttons is not the same as specified for <h1>. What is the reason for the same?
Code:
<div>
<p>Hellos!</p>
<h1>I'm Evans Gene<br>What's Up!</h1>
About me
See Profile
</div>
.pBtn {
color: #fff;
border: 1px solid #fff;
border-radius: 5px;
font-weight: 400;
margin: 20px 10px 0px 0px !important;
padding: 10px;
text-decoration: none;
}
The issue is the following:
Anchor tags can be used as buttons but <a> is different than <button>. And here, the orange highlighter depicting the margins of the <h1> sticks to the top of the text in <a>, instead of its top border, because it has border around it to make it look like a button, but semantically it is not a button.
To show the difference, just changing the <a> to <button> will shift downwards due to <margin-bottom> of <h1>.
Edit: From the comment of UncaughtTypeError User.
The issue is actually with the display type properties of the buttons in question, by default anchor tag elements (a) are computed as display: inline, this should be updated to display: inline-block to attribute block type properties to the elements (like margin values).

Inline-block vs inline elements in terms of line-breaks

Inside of a parent element which is a paragraph, there is text and a couple of anchor links. These anchor links have their display set to inline-block and the visual result looks like this:
https://imgur.com/a/aLR3Q
Now if I would change the display to inline, the result looks like this:
https://imgur.com/a/TFof9
My question is, why does having the display of the anchors set to inline-block instead of just inline cause this, let's just say "soft line break" ? Because I thought that in terms of line-breaks, both of the displays act in the same way, and don't break at all.
Codepen link for the code: https://codepen.io/Kestvir/pen/zpvmYV
The code for the parent element:
.footer__copyright {
border-top: 1px solid #777;
padding-top: 2rem;
width: 80%;
float: right;
}
The code for the anchors:
footer__link:link, .footer__link:visited {
color: #f7f7f7;
background-color: #333;
text-decoration: none;
text-transform: uppercase;
display: inline-block;
transition: all .2s;
}
The anchors are:
Jonas Schmedtmann
and
Advanced CSS and Sass
The line break happens because the the inline block cannot be split across multiple lines like a normal inline element. It is simply one entire "block unit" that is displayed inline. If that entire unit does not fit, then it will all be wrapped down to the next line.

How to target direct text and not text within tags?

Is there a way to only target the direct text within a <h1>-Tag?
Here is an example on what I want to do:
<h1>I want to select this text with a css selector <small>but not this text</small></h1>
This does not seem to work:
h1:not(small)
Is it even possible?
h1:not(small)
Your selector h1:not(small) doesn't work because it says this:
Target all h1 elements that are not small elements.
It's that same as using the h1 selector by itself.
h1 :not(small)
You would have been closer with h1 :not(small), which says:
Target all descendants of an h1 except small elements.
Boom! Exactly what you want.
Except that text contained directly inside an element (i.e, text with no tags around it) becomes an anonymous element. And anonymous elements are not selectable by CSS.
h1 :not(small) {
color: orange;
}
<h1>This text is contained directly inside the container. It is not selectable by CSS. It is an anonymous element. <small>This text is inside a small element</small></h1>
<hr>
<h1><span>This text is contained in a span. It is selectable by CSS</span> <small>This text is inside a small element</small></h1>
CSS Parent Selector
For the small element to be excluded it would have to identify itself as a child of the h1.
But there is no parent selector in CSS.
Solution: Two selectors
You need two selectors to make this work:
The first sets the style on the parent.
The second overrides the first on the child.
h1 {
color: orange;
}
h1 > small {
color: black;
}
<h1>I want to select this text with a css selector <small>but not this text</small></h1>
More Information
Targeting text nodes with CSS
Is it possible to style anonymous flex items explicitly?
Is it possible to select elements not preceded by text?
This is the closest it gets to retaining the style without any css that has been implemented by the parent div. This feature hasn't been fully integrated in all browsers, but it should work for some. Hope, it helps.
Browser support -
What's being done here?
The small tag is retaining its original CSS without being affected by the other styles. You can apply this on any of the child elements whose style you want to preserve.
small {
all: initial;
* {
all: unset;
}
}
h1 {
color: #ff0000;
}
<h1>I want to select this tex with a css selector <small>but not this text</small></h1>
Apply styles to h1 however you want, then, revert those changes in small, for example, if you only want to change the color you would use this code;
h1 { color: red; }
h1 small { color: initial; }
Or, if you have multiple style changes;
h1 {
color: red;
font-weight: italic;
text-transform: uppercase;
}
h1 small {
color: initial;
font-weight: initial;
text-transform: initial;
}
Please note that the initial CSS value can be used on every browser, except for IE and Opera Mini. View this page for more information

How to increase the height of the selected text's background?

I've been looking around Google but can't find a CSS way to increase the height of the background of selected text.
For example the background of the selected text in the Atom editor is noticeably higher than the right one:
Since Atom is made with HTML/CSS, I wonder if there's a combination of CSS which can achieve this result?
This is a bit hacky but you could do it by using a pseudo element (like ::before) that has a content of non-breaking space and some padding to create the line-height illusion:
body {
background: #000;
color: #FFF;
}
::selection {
background: red;
}
p::before {
content: "\00a0";
padding: 10px 0;
display: inline-block;
}
This is default text
<p>This text has a pseudo element</p>
jsFiddle: https://jsfiddle.net/azizn/8bmj4dm1/
Caveat: this will require wrapping each line in a tag. You could probably use JavaScript to automatically wrap each line in a tag for this to work with multi-line content.

How to wrap entire line with overline and underline , until the end of the line ?

I'm trying to underline and overline a line until the end of the line , but this CSS code
.statistics_lines {
text-decoration: overline underline;
}
only marks an underline & overline for the words only .
How can I force the entire line to be underlined , with the words ?
Like that :
There isn't a way using text-decoration since that style is the decoration added to the text of that element. You could use multiple spaces ( ) but it'd be sloppy and wouldn't always be the width of the element.
Since we are talking about a single line, you can use the border of your element to get what you are looking for. If the element is inline, you will need to change its display style.
I've also added padding:
.statistics_lines {
display:block;
border-top:1px solid #DDD;
border-bottom:1px solid #CCC;
padding:7px 4px;
}
<span class='statistics_lines'>this is my line</span>
Use border instead. Like this :
.element {
border-bottom: 1px solid #eee;
}
<div class="element">This is a test</div>
You can "play" with it in order to obtain any style you want. Example :
.element {
border-bottom: 1px dotted #888;
padding: 15px 0;
}
<div class="element">This is a test</div>
If you are talking about a single line then you may just use the border-top and border-bottom property for that.
But if you are talking about the multiple line sentences then you may use a background which width is to be just 1px and height would be the line height of your paragraph has and the background should repeat then you'll see exactly what you want.
Since the effects of text-decoration apply only to the textual content of the element, the only way to make them stretch across the available width is to make the content that wide. This could be done with JavaScript code that appends no-break spaces until the width is exceeded, then trace back one space. In plain CSS, you need to use a long string of no-break spaces (hoping that it will be enough) as generated content and to suppress overflow:
.statistics_lines {
text-decoration: overline underline;
white-space: nowrap;
overflow: hidden;
}
.statistics_lines:after {
content: "\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0\a0";
}
<div class=statistics_lines>this is my line</div>
Since overline and underline are too close to the letter glyphs in many ways, it is probably better to use upper and lower border instead, as suggested in other answers.