Is it possible to create a rule that will make the following HTML:
<div style="width: 100%"></div>
of one line height using just CSS, or do I need to put as the content?
Some possibilities:
Set height (or min-height) to the line-height's used value.
The initial value of line-height is normal, whose used value is implementation-dependent, but the spec suggests a number between 1.0 and 1.2
In my case (FF27 for winXP with font-family: "times new roman") that value is 1.25, so you could use height: 1.25em. However, that value might be different with other fonts or implementations.
Then, it's better to manually set line-height to some value, like line-height: 1.25em.
div {
border: 1px solid red;
min-height: 1.25em;
line-height: 1.25;
}
<div></div>
Note that if you want to set those styles to the elements only when it has no content, you can use the :empty pseudo-class:
div:empty {
border: 1px solid red;
height: 1.25em;
line-height: 1.25;
}
<div></div>
Inserting some content to the element.
For example, you can add a normal space and set white-space to pre-wrap (or pre) to prevent the space from collapsing:
div {
border: 1px solid red;
white-space: pre-wrap;
}
<div> </div>
Alternatively, you can use a zero-width space ()
div { border: 1px solid red; }
<div></div><!-- There is a zero-width space inside -->
As you say, would also work. However, it is a non-breaking space, so its purpose is preventing automatic line breaks. Then, using it would be semantically incorrect IMO.
And as #BoltClock says, those whitespaces could be inserted with CSS pseudo-elements, but note that might not work on very old browsers.
Just another solution:
.your-selector:empty::after {
content: ".";
visibility: hidden;
}
That depends on your definition of a single-line height, since there isn't a CSS unit that corresponds to the computed line height of an element.
If you know the exact line-height value for this element, then you can just explicitly set height to the same value. But, given your question, this is likely not the case.
There is a unit that corresponds to font size, em, which you can use if the height of one line is equal to the computed font size:
<div style="width: 100%; height: 1em"></div>
Otherwise you will have to put in some sort of filler content. You can either throw in an and be done with it:
<div style="width: 100%"> </div>
Or go a little overkill by writing a CSS rule with a pseudo-element, but you must be able to target this element somehow:
div::before { content: '\00a0'; }
If the element may or may not have content but you want it to have a minimum height,
use min-height where you would have used height instead, or
select div:empty::before instead if you choose to use a pseudo-element so the filler doesn't get inserted if there is content.
The solution with visibility: hidden; is clever. It is simpler to set the content to Unicode character feff, which is the byte order mark. This has no width but has height; it behaves the same on every browser all the way back to IE6.
.your-selector:empty::before {
content: '\feff';
}
I have found that WebKit (at least on Mac OS) applies slightly different (1px) line height to bold text than normal text for some fonts. To enforce uniformity (in this case, we would need to apply even to non-empty selectors):
.your-selector::before {
content: '\feff';
font-weight: 900;
}
The problem I had was with jQuery Terminal that needed to have empty line same size of normal lines. Other solution was problematic because when using fixed line-height there was gaps between lines also there was bug in Firefox that I've reported about layout with font-size + line-height.
By best solution so far is this:
div::before {
content: '\0200B';
float: left;
display: block;
}
and no line-height/min-height in the code and it works perfectly. Also when not using line-height it have good looking style selection without gaps.
What height do you want to keep? Will that be in relation with your font-size? That can be in em, pt, px or %.
This is just an example where 1.5em is arbitrary value:
<div style="width: 100%; height: 5px" ></div>
If you don't have anything to write in this div, use some height value.
Related
I have an anchor tag, and I'm using the :before selector to add some text. I have added a hover state around the anchor tag. The :before text is slightly larger than the rest of the text in the anchor tag and I'm adding a display: inline-block property to the before text.
When I hover over the anchor tag, the hover state is wrapped tightly around the all the anchor text, including the :before text (EXAMPLE 1 in codepen). Like so:
https://user-images.githubusercontent.com/20184809/52691191-27364e80-2fb4-11e9-9ffe-8777e645acee.png
How ever if I add the display:inline-block property to the anchor tag the hover state is a rectangle which matches the height of the larger :before text. Like so:
https://user-images.githubusercontent.com/20184809/52691272-7da38d00-2fb4-11e9-900b-c795623de3e2.png
Why is this?
.link-1:hover, .link-2:hover {
outline: 3px solid green;
outline-offset: 2px;
}
.link:before {
content:':before text';
font-size: 35px;
display: inline-block;
}
.link-1 {
display: inline-block;
}
<!-- EXAMPLE 2 -->
anchor text
<br>
<!-- EXAMPLE 1 -->
anchor text
EDIT:
I've noticed this happens on Chrome and not Safari and firefox. It could be a browser thing?
From the specification we can read:
Outlines may be non-rectangular. For example, if the element is broken across several lines, the outline is the minimum outline that encloses all the element's boxes. In contrast to borders, the outline is not open at the line box's end or start, but is always fully connected if possible.
And
The outline may be drawn starting just outside the border edge.
For the second example, when making the element inline-block we will have the below
.link-1:hover, .link-2:hover {
outline: 3px solid green;
outline-offset: 2px;
}
.link:before {
content:':before text';
font-size: 35px;
display: inline-block;
}
.link-1 {
display: inline-block;
border:1px solid;
}
anchor text
It's clear that the outline need to at least surround the border and it will be the same for all the browser.
But for the first example we will have this:
.link-1:hover, .link-2:hover {
outline: 3px solid green;
outline-offset: 2px;
}
.link:before {
content:':before text';
font-size: 35px;
display: inline-block;
}
.link,
.link:before{
border:1px solid;
}
<!-- EXAMPLE 2 -->
anchor text
It seems that Chrome in this case is following the borders to draw the outline and is respecting the Specification by keeping it connected. The result is somehow logical but other browser aren't doing the same. I won't say if Firefox is doing wrong but both result are fine and doesn't violate the specification.
In both cases we have :
The minimum outline that encloses all the element's boxes
Always fully connected if possible
May be drawn starting just outside the border edge
There are two types of HTML elements. Inline and Block elements. Block elements take up the full width available to them(With exception of inline blocks, will come back to these). Inline elements only take up as much space as they need, i.e they try to be as small as possible. So just the space around their outer border. When you add display: inline-block you turn the whole thing into a block which is why it becomes rectangular. The difference with inline-blocks is that they also take up as much space as they need but they are also fully rectangular. Check out this answer too CSS display: inline vs inline-block
Given this:
<h1>This is a test <small>It is</small></h1>
Is there any CSS I could apply to the <small> that would have it appear BEFORE, and ON THE PREVIOUS LINE, before "This is..."? float:left; display:block; doesn't get it before the content.
In a relatively simple case like this, you can use positioning. Declare the heading as relatively positioned, set a suitable top padding on it, and make the small element “absolutely” positioned (i.e., positioned relative to its positioned ancestor, the heading). Example:
h1 { position: relative; padding-top: 1em; }
h1 small { position: absolute; top: 0; left: 0; height: 1.3em; }
Note that when setting the padding, em denotes the font size of the h1 element, whereas when declaring the height of the inner element, the small element, em denotes its font size, which is smaller. Hence 1em vs. 1.3em, even though the padding is meant to give room for the small element. You probably want to set font sizes on h1 and small (say, h1 { font-size: 150% } small { font-size: 80% }) to get more predictable rendering, and then experiment with the padding and height values to get the appearance you like. This tuning will also depend on the font.
Here it is:
HTML:
<h1 id="thisid">This is a test <small>It is</small></h1>
CSS:
#thisid:before {
content:"This is the content on the line above \A ";
white-space: pre;
}
The :before pseudo element will make the stuff go before. Whereas the \A will make a space break.
Here is the fiddle: http://jsfiddle.net/pikk/ZL54q/
I'm trying to add an image with the &::before pseudo element and place it on top of it's parent element by adjusting the padding/margin. I have not be able to place the img "on top" of it's parent element. It resides within the box of the parent. I have tried setting both elements to display:block. I have attempted to use relative/absolute positioning. I have adjusted margins/padding without a solution.
HTML:
<div class="foo">
<div class="title">title</div>
<div class="body">text</div>
</div>
LESS/CSS:
.foo {
display:block;
padding: 1em;
&:before {
background-image: url("bar.svg");
padding: .25in;
background-repeat: no-repeat;
background-position: top left;
background-position: top outside;
background-color: white;
content: "";
display: block;
max-width: (#column + .45in);
margin-left: -.15in;
margin-top:-.5in;
}
}
I would expect adjusting the value of the margins on the pseudo element would produce the expected result. However this is not the case. Is there a limitation I'm unaware of?
Thanks for your time and your help.
First, I assume by "on top" you mean displayed "before" the .foo element. I assume that based on what it appears you are trying to do with your code. Normally, I would interpret "on top" as a higher z-index and overlapping an element, but I don't think that is what you are asking.
Second, unless I am unfamiliar with something (definitely possible), there is no outside keyword for background-position; therefore, that would seem to be an error (though I would not expect it to cause the issue you face).
Third, I would think that your basic premise should be working. This fiddle demonstrates a shifting of the :before element to be "before" its .foo parent. It could be your mixed use of em units and in units is causing some issues. That would not be a good way to insure you get the positioning you want. I would keep your units in em.
Pseudo-elements are displayed inline by default. Also, they are placed within the content area of an element.
To make it appear 'on top' of that element, set the display to block.
Lastly, pseudo-elements should be initialized using the content property.
.foo::before {
content: url(./bar.svg);
display: block;
}
Bear with me here, but assuming this code:
<style>
span {
color: black;
background-color: black;
}
</style>
<span>Hello world</span>
Hello world
Gives a result that looks like this:
███████████
Is it possible to apply style to just the letter height, versus the font/line height? In effect ending up with something that looks like this:
█▄██▄ ▄▄▄██
No (not with a background color anyway). Background colors apply to the entire element (e.g., span element), which is essentially a box as determined by the CSS box model. The official recommendation from the W3C specifies that a background color will fill the content, padding, and border areas of the box model. The CSS3 background (candidate recommendation) offers a bit more power for you to control where background colors apply, but not much.
If you really want the effect you've just demonstrated in your question, I think a JavaScript function to convert "short" characters (e.g., "w") to "▄" and "tall" characters (e.g., "h") to "█" would work nicely. Here's a demo on jsfiddle.
I can't think of a way using ONLY CSS, but you could use a function in PHP like imagefontheight: http://php.net/manual/en/function.imagefontheight.php and dynamically create your block elements from the specified font...
The only way I can think of to get the effect purely by CSS requires:
An obscenely excessive amount of extra html markup.
A willingness to allow for some slight inexactness to the height of the background in comparison to the character itself.
A meticulous amount of testing on the particular font(s) you are going to use it on to see what results you are likely to get across browsers.
In other words: it really better be well worth the effort, and it probably ought to be used on only a very short string of text.
Here's an example fiddle with the word color left contrasting to see how the background fits the letters. Note: this undoubtedly will have some variation on height and spacing above/below letters based on browser and font's being seen by you. The use of a :before pseudo-element to achieve the effect means accommodations would need to be made for older browsers (IE7 and under).
Here's the basic code in the fiddle.
<span>H</span><span class="short">e</span><span>l</span><span>l</span><span class="short">o</span><span class="short">w</span> <span class="short">w</span><span class="short">o</span><span class="short">r</span><span>l</span><span>d</span>
span {
color: white;
display: inline-block;
position: relative;
height: 1em;
}
span:before {
content: '';
position: absolute;
top: .2em;
right: 0;
bottom: .1em;
left: 0;
background-color: black;
z-index: -1;
}
span.short:before {
top: .4em;
}
I'm setting a height of 20px on a <div>, though when it renders in the browser, its only 14px high.
Any ideas?
<div style="display:inline; height:20px width: 70px">My Text Here</div>
You cannot set height and width for elements with display:inline;. Use display:inline-block; instead.
From the CSS2 spec:
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. A UA may, e.g., use the em-box or the maximum ascender and descender of the font. (The latter would ensure that glyphs with parts above or below the em-box still fall within the content area, but leads to differently sized boxes for different fonts; the former would ensure authors can control background styling relative to the 'line-height', but leads to glyphs painting outside their content area.)
EDIT — You're also missing a ; terminator for the height property:
<div style="display:inline; height:20px width: 70px">My Text Here</div>
<!-- ^^ here -->
Working example: http://jsfiddle.net/FpqtJ/
This worked for me:
min-height: 14px;
height: 14px;
Also, make sure you add ";" to each style. Your excluding them from width and height and while it might not be causing your specific problem, it's important to close it.
<div style="height:20px; width: 70px;">My Text Here</div>
You're loosing your height attribute because you're changing the block element to inline (it's now going to act like a <p>). You're probably picking up that 14px height because of the text height inside your in-line div.
Inline-block may work for your needs, but you may have to implement a work around or two for cross-browser support.
IE supports inline-block, but only for elements that are natively inline.
Set positioning to absolute. That will solve the problem immediately, but might cause some problems in layout later. You can always figure out a way around them ;)
Example:
position:absolute;
Position absolute fixes it for me. I suggest also adding a semi-colon if you haven't already.
.container {
width: 22.5%;
size: 22.5% 22.5%;
margin-top: 0%;
border-radius: 10px;
background-color: floralwhite;
display:inline-block;
min-height: 20%;
position: absolute;
height: 50%;
}
You try to set the height property of an inline element, which is not possible. You can try to make it a block element, or perhaps you meant to alter the line-height property?
I'm told that it's bad practice to overuse it, but you can always add !important after your code to prioritize the css properties value.
.p{height:400px!important;}
use the min-height property. min-height:20px;