Consistens width of :first-letter with CSS - css

I’m trying to draw a circle around the first letter of each first paragraph in an article using border-radius and padding, but because of the different widths of the characters, it will be displayed as an ellipse rather than as a circle.
Is there any possibility to set width and height of a letter to the same amount with CSS or to set the padding so that it matches together with the width the height of any character?
My current code looks like this:
p:first-of-type:first-letter{
font-size: 58px;
line-height: 1;
float: left;
margin-bottom: -4px;
background-color: rgb(44, 44, 44);
border-radius: 40px;
padding: 0 14px;
color: #fff;
}

Per #web-tiki - The ::first-letter pseudo element doesn't allow the width property. The only solution would be to use a monospace font or to use a container for the first letter. It would allow specifying a with for it an keep the circle round.
Building on web-tiki's excellent answer, you could size everything in em so it reacts to font-size changes as well.
span {
font-size: 58px;
width: 1.5em;
height: 1.5em;
line-height: 1.5em;
display: inline-block;
vertical-align: middle;
background-color: rgb(44, 44, 44);
border-radius: 50%;
color: #fff;
text-align: center;
margin-right: .1em
}
p:nth-of-type(even) span {
font-size: 24px;
}
<p><span>A</span>pple</p>
<p><span>Q</span>uestionable</p>

For those who may not want to add an extra element around each first letter, another solution would be using a svg as a background-image:
p:first-of-type:first-letter{
background-image:url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSI1OCIgd2lkdGg9IjU4Ij4KICA8Y2lyY2xlIGN4ID0iMjkiIGN5ID0iMjkiIHIgPSIyOSIgc3R5bGU9ImZpbGw6IzQ0NDQ0NDtzdHJva2U6bm9uZTsiIC8+Cjwvc3ZnPgo=");
padding:0px 15px;
background-repeat:no-repeat;
background-position:center center;
}

Related

How to make :after pseudo element responsive

I created a Wordpress site and I added a blockquote element in the about section of the homepage.
I used :before and :after to insert a qoute unicode in my blockquote element but the problem is the :after pseudo quote is not responsive.
I inserted a top: 45% right: 34% temporarily and it works only for min-width: 1200px screensize.
blockquote {
display:block;
background: #fff;
padding: 20px 20px 20px 75px;
margin: 0 0 20px;
position: relative;
width: 100%;
/*Font*/
font-family: Georgia, serif;
font-style: italic;
font-size: 36px;
line-height: 1.2;
color: #242424;
}
blockquote::before{
content: "\201C";
font-family: Georgia, serif;
font-size: 100px;
font-weight: bold;
color: #FFC107;
/*Positioning*/
position: absolute;
left: 10px;
top: -10px;
}
blockquote::after{
content: "\201D";
font-family: Georgia, serif;
font-size: 100px;
font-weight: bold;
color: #FFC107;
position: absolute;
top: 45%;
right: 34%;
}
I am not sure what you mean by "not responsive" ("responsive" isn't a very well-defined term...), but I assume you mean that the position of the inserted ::after element is only correct at a specific window size?
The opening quotation mark always appears at the same position relative to the text, but the closing mark is positioned to the edge of the <blockquote> element, not the end of the text inside it. At some window sizes, when the text wrapping leaves a large gap between the last word of the text and the edge of the element, the quotation mark is separated from the text. This is made worse because of the large font size.
In your specific case, a simple solution is to change the blockquote::after selector to blockquote p::after, and remove the top:45% and right:34% properties. The ::after element is then inserted at the end of the text, which means its position changes as the text reflows.
I was able to solve a similar issue by just adding this:
width: inherit;

Calculate text height properly independently of font used to make a text element with a right arrow

I'm trying to create a label that has a right arrow. It looks like this:
The code I'm using is the following (LESS):
#font-size: 14px;
#padding-top: 4px;
#arrow-bheight: #font-size;
.label {
position: relative;
font-size: #font-size;
font-weight: normal;
font-style: italic;
text-transform: uppercase;
padding: #padding-top 8px;
line-height: 1;
color: #fff;
background: #000;
&:after {
content: "";
width: 0;
height: 0;
border-top: #arrow-bheight solid transparent;
border-bottom: #arrow-bheight solid transparent;
border-left: #arrow-bheight solid #000;
position: absolute;
right: -#arrow-bheight;
top:0;
}
}
My problem is that depending on the font we use, the arrow doesn't fit perfectly into the text font.
I've been trying to set a specific value for the line-height, e.g. line-height: #font-size, but it's not working.
Here's a CodePen of the problem.
How can I make the right arrow have the proper height regardless of the font used?
There's no need to define #padding-top variable separately. Instead you could use em unit which is relative to the element's font-size.
Also you should change the display type of the labels to inline-block:
Updated Example
.label {
display: inline-block;
font-size: #font-size; /* This has been set to 14px */
padding: 0.5em 8px; /* The computed value of 0.5em would be 14px/2 = 7px */
line-height: 1;
/* other declarations... omitted due to brevity */
}
Two things that may help...
The background-position edge offsets and the CSS calc unit.
I'm not familiar with the first though CSS calc will let you do things such as...
height: calc(100% - 24px);

How to select only one child element in CSS?

I'm trying to make a box with a header, a first paragraph, and a second paragraph. How can I select only the last paragraph in CSS so I can move it down, so it isn't overlapping the first paragraph? This is the code I have:
#info-box > p {
line-height: 1.3em;
font-size: 17px;
font-family: Arial;
text-align: center;
color: #979797;
margin-left: 20px;
margin-right: 20px;
margin-top: 0px;
position: absolute;
}
#info-box:nth-child(2) {
line-height: 1.3em;
font-size: 17px;
font-family: Arial;
text-align: center;
color: #979797;
margin-left: 20px;
margin-right: 20px;
margin-top: 100px;
position: absolute;
}
You're looking for :last-child
Quoting the specification:
The :last-child pseudo-class represents an element that is the last child of some other element.
Here's an example:
div {
width:100px;
height:100px;
background-color:red;
border:solid;
margin:2px;
display:inline-block;
border-width:1px;
}
div:last-child{
background-color:white;
}
Although to be fair, absolute position is rarely "the way" like Nit implied in the comments. Fixed sizes in pixel don't work too well on different screen sizes and different zooms, prefer a more logical layout. See this question on why.
CSS for last element try to use :last-child
#info-box:last-child {
}
Check here for reference CSS selector
http://www.w3schools.com/cssref/css_selectors.asp

Restrict border width to text width in a block element

I have an <h2> title into a fixed with <div> (238px). When this page is rendered, the browser manage line breaks into the title to make the text fit the width (238px).
But the width property of the h2 element is still 238px, no matters where the line breaks are.
I want to set a border-bottom only under the text, and not under the full width of the h2 element, and I don't know how to achieve this using CSS.
You can see what I mean here : http://jsfiddle.net/np3rJ/2/
Thanks
I think this is what you need:
<h2><span>Horizon 2020, nouvelles opportunités</span></h2>
h2 span {
position: relative;
padding-bottom: 5px;
}
h2 span::after{
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
border-bottom: 1px solid #000;
content: ""
}
Working demo in jsFiddle
I used the technique described in this answer: Advanced CSS challenge: underline only the final line of text with CSS
I introduced a span into the H2 in order not to change the display attribute of it, but you could just as easily use the same technique with a display: inline on your H2. This method would allow the control of the actual line though rather than setting display: inline if needed
This works on Chrome.
h2 {
width: fit-content;
}
If you are willing to use display: table-cell, and pseudo-elements, you can have a pretty good solution (with some minor limitations).
The HTML does not change:
<div class="dossier_titre">
<h2>Horizon 2020, nouvelles opportunités</h2>
</div>
and you can apply the following CSS:
.zone_33 {
width: 238px;
padding: 0px;
margin: 0px;
}
.zone_33 .dossier_titre {
margin: 0px 0px 20px 0px;
}
.zone_33 h2 {
color: #616263;
font-size: 150%;
font-weight: lighter;
padding: 0px 0px 12px 0px;
background: none;
border-bottom: 1px solid grey;
display: table-cell;
text-transform: uppercase;
}
.zone_33 .dossier_titre:after {
content: "";
display: table-cell;
width: 100%;
}
For the <h2> element, set display: table-cell, and add a pseudo-element after .dossier_titre (the containing block for the header/title element). The pseudo-element is also a table-cell and has a width of 100% (this is the key).
Also, since h2 is no longer a block element, add your margins to .dossier_titre to maintain the visual spacing in our layout.
How This Works
I am creating a two-cell table with the second cell (the pseudo-element) having a width of 100%. This triggers the browser to calculate the shrink-to-fit width for the first cell (h2) that contains the title text. The first cell's width is thus the minimal needed to display the text. The bottom border is as long as the longest text line in the text block within the table-cell.
Limitations
table-cell is not supported in IE7 without a hack, but the work-around is fairly well known and can be found if needed.
If the title had many short words, you might get the line breaking in unexpected places. You would need to insert &nbsp to keep specific words together as needed.
Fiddle: http://jsfiddle.net/audetwebdesign/h34pL/
Maybe display: inline-block; Or display: inline; is what you need?
Why not try:
text-decoration:underline
?
EDIT
Just make a span around "OPPORTUNITÉS" with the underline.
<h2>Horizon 2020, nouvelles <span class="underline">opportunités</span> </h2>
.underline {
text-decoration:underline
}
Can try "text-underline-position" property instead of table-cell and border. Make it simple!
text-decoration: underline;
text-underline-position: under;
All you can do is put your h2 element text into span like this:
<h2><span>Horizon 2020, nouvelles opportunités</span></h2>
and in css remove border-bottom from .zone_33 h2 {} and put it like this:
.zone_33 h2 span{ border-bottom: 1px solid grey;}
by this border-bottom will come under full text.
Try this, (I think it will help you)
.heading {
position: relative;
color: $gray-light;
font-weight: 700;
bottom: 5px;
padding-bottom: 5px;
display:inline-block;
}
.heading::after {
position: absolute;
display:inline-block;
border: 1px solid $brand-primary !important;
bottom: -1px;
content: "";
height: 2px;
left: 0;
width: 100%;
}
You could put a border-bottom and change the width of your h2 so that the border length matches your h2 length. Adjust the width to the width of your h2, taking into consideration it's font-size. Then add a padding-bottom to your h2 and set it to your liking.
<h2>Cats</h2>
h2{
border-bottom: 5px solid black;
font-size: 16px;
padding-bottom: 5px;
width: 64px;
}

Solving cross-browser type discrepencies?

My aim is have the text inside this div displaying in the middle of it's container cross-browser.
If I could achieve this it would enable me to use fewer images.
http://jsfiddle.net/tMFaD/
Notice how this example looks different in Chrome/Safari and Firefox. The issue seems obviously related to the type/line-height/similar (the '1' is higher up on firefox).
Can this be easily done?
UPDATE: This is the small difference that i'm trying to solve: http://cl.ly/2A2o371c2O2r3q0T0R2E
UPDATE 2: I have not found a definitive cross-browser solution but some of the answers in this thread should come close enough for most. The solution I used was to use a browser-targeted rule for this element. I could also have used images/sprites.
You could set line-height to match the height of the box and then remove the top and bottom padding. That will align it in the (vertical) middle of the box.
You can do it in a couple of ways:
.box {
font-size: 44px;
font-weight: bold;
color: white;
text-align: center;
background: pink;
display: table-cell;
vertical-align: middle;
text-align: center;
width: 80px;
height: 80px;
}​
.box {
width: 80px;
height: 80px;
font-size: 44px;
line-height: 80px;
font-weight: bold;
color: white;
background: pink;
text-align: center;
}
Both will produce the same results:
http://jsfiddle.net/spacebeers/s9Urm/8/
EDIT: To get the level or cross browser/cross OS precision you're after I think you're going to have to use separate style rules for some of them or just use images.
OTHER suggestion, use line-height to control vertical middle instead of padding:
.box {
display:block;
font-size: 44px;
font-weight: bold;
color: white;
text-align: center;
background: pink;
float: left;
line-height:80px;
width:80px;
height:80px;
}​

Resources