Responsive CSS transform for before pseudo-element - css

The effect I am after here is to show the word "Introducing" in the before pseudo element for an h1 header that has its own content centered. My effort thus far is shown below
h1::before
{
font-size:0.7rem;
content:'Introducing';
position:absolute;
left:calc(50% - 6em);
top:-0.75em;
transform:rotate(-45deg);
}
h1
{
text-align:center;
position:relative;
margin-top:30px;
}
<h1>
Hello
</h1>
This works and, as far as I can tell, is responsive - the before pseudo retains its placement relative to its parent. However, I suspect that this is not the right solution. Hopefully, someone here can suggest a better way.

Your current solution is responsive about different screen sizes, but it isn't about different h1 lengths. A longer text will need a different position.
You can solve it make the width of h1 adjust to its content. And now, just position the pseudo on the upper left, center it with a translation and rotate it.
h1::before {
font-size: 0.7rem;
content: 'Introducing';
position: absolute;
top: -1em;
transform: translateX(-50%) rotate(-45deg);
}
h1 {
text-align: center;
position: relative;
margin: 30px auto;
width: fit-content;
background-color: cadetblue;
}
<h1>
Hello
</h1>
<h1>
Hello World
</h1>

Related

Adding a shaped border-bottom to the section heading

I am looking for a design like the following screenshot for the section heading. ( The bottom line)
So far I could achieve
h1 {
position: relative;
text-align: center;
width: 100%;
}
h1:after {
content: '';
position: absolute;
width: 100px;
left: 50%;
transform: translateX(-50%);
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
bottom: 0;
border-bottom: 3px solid #8d8f90;
}
<h1 style="text-transform: none">How it works</h1>
Now I want the both end of the border-bottom to be shaped.
Example of using responsive background-image as requested in comments!
So im assuming that the border image will need to be that same length as the text, here is a working example:
div {
text-align: center;
}
h1 {
display: inline-block;
background-image: url(https://ded7t1cra1lh5.cloudfront.net/media/76045/a7fdf291661d9baab9b767d833c70183ba6ee3ce/original/divider-37709_1280.png?1448468523);
height: 120px;
background-repeat: no-repeat;
background-position: center;
background-size: cover/*contain*/
;
}
<div>
<h1 id="_1">I am a header</h1>
</div>
<div>
<h1 id="_2">I am a really really really really long header</h1>
</div>
So in this i grabbed a pretty large image from google as an example so it wouldnt be stretched at larger screen sizes. You will need to use #media screen command to alter the height of the header tag when the text breaks. However this will only be needed on longer headers, and if the header border needs to be the same length as the text. If it doesnt you can use a much shorter image and possibly change the size from cover to contain. The inline block makes it so the background image will always be the length of the text as well.
If you do decide to go this route some minor tweaking to the css should yield you acceptable results. Hope this is helpful as a back up solution Ramesh!

Background / border behind and below text (CSS)

I am looking to create this effect with css: https://i.stack.imgur.com/zpzVC.png
Since I don't know how this effect is called, I haven't been able to find a solution online and I can't make it work on my own unfortunately.
The effect repeats a few times on different titles with different sizes. The border should begin on the half of the first letter.
Who can help me?
I'd use the :after pseudo class on the span element to accomplish this.
body {
background: #3E9CE2;
color: white;
font-family: sans-serif;
} /* Just for looks */
h1 span {
position: relative;
display: inline-block;
}
h1 span:after {
position: relative;
display: block;
content: "";
background: #DE2F2D;
z-index: -5;
height: 22px;
top: -19px;
left: 7px;
}
<h1>This is our <span class="offset-background">showcase</span></h1>
The position and display attributes on the span itself make sure the :after element is properly positioned (directly underneath the span) and has the same width as the text.
The pseudo element has to define its height and a position offset, as well as a negative z-index to make sure it's drawn behind the text.
Here is an example of what you seem to be looking for. The solution I used is to offset a box around the text and negatively offset the text the same amount.
h1 span { position: relative; display: inline-block; }
.blue-sq{
background-color:blue;
display:inline-block;
}
.offset-red{
position:relative;
top:22px;
background-color:red;
height:18px;
}
.inner-text{
position:relative;
top:-22px;
left:-6px;
}
<div class="blue-sq">
<h1>View our
<span class="offset-red">
<span class="inner-text">showcase</span>
</span>
</h1>
</div>

Why CSS3 is not supporting vertical center (directly)?

One very common question on CSS is how to vertically center an element. With CSS3 being able to do so many special effect, why they are not including the vertically center function into CSS3?
I don't believe it is a difficult function to add if even a beginner developer can make a function to center things with javascript. And with so many hacks for different situations, it is clear that with CSS alone it is possible to center things vertically. So maybe there are other reasons that they decide not to make it a standard property?
That is because how layout is performed with CSS — CSS is predominantly arranging items on the x-axis, like how 100% width works as expected but not 100% height. This is likely due to the possible "calculation/logic loop" that happens as width is dependent on height and vice versa, so one axis must always be prioritized when it comes to calculation.
Extra info by #BoltClock:
The x-axis thing has to do with the natural flow of text in a
document. Remember that the Web started off as a series of pages, so
HTML and CSS were originally built around this fundamental premise -
it has since evolved into an application platform, but the legacy is
still there. Flexbox is the CSS3 way to vertically center boxes - the
only issue is cross-browser support, but since the question is about
CSS3 anyway, that's to be expected.
Similarly, in terms of dictating alignment, horizontal alignment is easy because the width of an element is often implicitly or explicitly stated, like how a block element automatically has a implicit width of 100% unless otherwise stated, allowing for easy calculation of a center position along the horizontal axis.
However, this does not work for the case of vertical alignment, where often than not the vertical dimension is dependent on the amount, length and size of the content. In the case where vertical height is explicitly stated, this can actually be easily done:
by using the CSS flexbox method
The good: standards compliant and very simple, dimension of element of interest does not have to be fixed
The bad: lack of extensive cross-browser support, but appears very promising today
body {
margin: 0;
padding: 0;
}
.box {
background-color: #eee;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100vh;
}
.box > .content {
background-color: #333;
color: #eee;
padding: 1em 2em;
}
<div class="box">
<div class="content">I am centered</div>
</div>
by using absolute positioning and CSS transforms
The good: extensive cross-browser support, dimension of element of interest does not have to be fixed
The bad: fuzzy text rendering (occasionally) due to sub-pixel translation
body {
margin: 0;
padding: 0;
}
.box {
background-color: #eee;
position: relatve;
width: 100%;
height: 100vh;
}
.box > .content {
background-color: #333;
color: #eee;
padding: 1em 2em;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
<div class="box">
<div class="content">I am centered</div>
</div>
by using absolute positioning and negative margins
The good: extremely straightforward
The bad: dimension of element of interest MUST be fixed
body {
margin: 0;
padding: 0;
}
.box {
background-color: #eee;
position: relative;
width: 100%;
height: 100vh;
}
.box > .content {
background-color: #333;
color: #eee;
width: 200px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -100px;
}
<div class="box">
<div class="content">I am centered</div>
</div>

Off by one pixel issue in IE CSS transform

I am using transform: skew to create the effect of a down arrow on my banner image using both the :before and :after tags. The result should look like the following:
However, in IE 9-11 there seems to be a rounding issue. At some heights there is one pixel from the background image that shows below the skewed blocks resulting in the following:
In my case, the banner is a percentage of the total height of the window. Here is the some sample code which should be able to reproduce the problem:
HTML
<div id="main">
<div id="banner"></div>
<section>
<h1>...</h1>
<p>...</p>
</section>
</div>
CSS
#banner {
position: relative;
background-color: green;
width: 100%;
height: 75%;
overflow: hidden;
}
#banner:before,
#banner:after {
content: '';
display: block;
position: absolute;
bottom: 0;
width: 50%;
height: 1.5em;
background-color: #FFFFF9;
transform: skew(45deg);
transform-origin: right bottom;
}
#banner:after {
right: 0;
transform: skew(-45deg);
transform-origin: left bottom;
}
body {
background-color: #333;
position: absolute;
width: 100%;
height: 100%;
}
#main {
max-width: 40em;
margin: 0 auto;
background-color: #FFFFF9;
position: relative;
height: 100%;
}
section {
padding: 0 1em 5em;
background-color: #FFFFF9;
}
And here a working example.
Yes, seems to be a rounding issue – and I don’t know of anything that one could do to fix this. It’s in the nature of percentage values that they don’t always result in full pixel values – and how rounding is done in those cases is up to the browser vendor, I’m afraid.
I can only offer you a possible workaround (resp. “cover up”) that seems to work – if the layout really is as simple as this, and the main content area has a white background, and no transparency or background-image gets involved there.
Pull the section “up” over the banner by a negative margin of -1px (eliminated top margin of h1 here as well, otherwise it adjoins with the top margin of the section – countered by a padding-top), so that its background simply covers up that little glitch:
section {
padding: 1em 1em 5em;
background-color: #FFFFF9;
position:relative;
margin-top:-1px;
}
section h1:first-child { margin-top:0; }
Well, if you look closely, that makes the corner of triangle look slightly “cut off” (by one pixel) in those situations where the rounding glitch occurs – if you can live with that (and your desired layout allows for it), then take it :-) (And maybe serve it to IE only by some means). If not – then sorry, can’t help you there.

Vertically center rotated text with CSS

I have the following HTML:
<div class="outer">
<div class="inner rotate">Centered?</div>
</div>
div.outer is a narrow vertical strip. div.inner is rotated 90 degrees. I would like the text "Centered?" to appear centered in its container div. I do not know the size of either div in advance.
This comes close: http://jsfiddle.net/CCMyf/2/. You can see from the jsfiddle that the text is vertically centered before the transform: rotate(-90deg) style is applied, but is somewhat offset after. This is particularly noticeable when div.outer is short.
Is it possible to center this text vertically without knowing any of the sizes in advance? I haven't found any values of transform-origin that solve this problem.
The key is to set position top and left to 50% and then transformX and transformY to -50%.
.inner {
position: absolute;
top: 50%;
left: 50%;
}
.rotate {
transform: translateX(-50%) translateY(-50%) rotate(-90deg);
}
see: http://jsfiddle.net/CCMyf/79/
It may be a bit late for answering that question, but I stumbled on the same issue and found some way of achieving it, by adding another div in the way.
<div class="outer">
<div class='middle'><span class="inner rotate">Centered?</span></div>
</div>
and applying a text-align: center on that middle element, along with some positioning stuff:
.middle {
margin-left: -200px;
width: 400px;
text-align: center;
position: relative;
left: 7px;
top: 50%;
line-height: 37px;
}
The .inner also gets a display: inline-block; to enable both rotate and text-align properties.
Here is the corresponding fiddle : http://jsfiddle.net/CCMyf/47/
The another option to rotate text 90 degree and center on axis Y is:
.rotate-centered {
top: 50%;
right: 50%;
position: absolute;
transform: scale(-1) translate(-50%, 50%);
writing-mode: vertical-lr;
}
<span class="rotate-centered">Text<span>
Example: https://codepen.io/wwwebman/pen/KKwqErL
But because of bad support in IE/EDGE writing-mode does NOT work there:
https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode
Can you add margin: 0 auto; to your "rotate" class to center the text.
.rotate {
-webkit-transform: rotate(-90deg);
-ff-transform: rotate(-90deg);
transform: rotate(-90deg);
width: 16px; /* transform: rotate() does not rotate the bounding box. */
margin: 0 auto;
}
The answer from 'bjnsn' is good but not perfect as it fails when the text contains space in it. For example he used 'Centered?' as text but if we changed the text to let suppose 'Centered? or not' then it will not work fine and will take the next line after space. Ther is not width or height defined for the inner div block.
.inner {
font-size: 13px;
font-color: #878787;
position: absolute;
top: 50%;
left: 50%;
background: #DDD;
}
https://jsfiddle.net/touqeer_shakeel/f1gfy1yy/
But we can make the whole text centered align properly, by setting the inner div width equal to height of the outer div, line-height of inner div equal to the width of the outer div and setting the display flex property for inner div with align-items:center and justify-content:center properties.
.inner {
font-size: 13px;
font-color: #878787;
position: absolute;
top: 50%;
left: 50%;
display: flex;
justify-content:center;
align-items:center;
line-height:40px;
}
$('#height').on('change', function(e) {
$('.outer').css('height', $('#height').val() + 'px');
$('.inner').css('width', $('#height').val() + 'px');
});
updated fiddle https://jsfiddle.net/touqeer_shakeel/cjL21of5/
Removing : margin-top: -7px; from .inner made the vertically rotated text centered for me. It also made the horizontal text not centered.
Just remove the above code?
You could add this:
$('.inner').css('margin-top', $(this).parent().height() - 2*$(this).height());
To your .on('change') function, as you can see here: http://jsfiddle.net/darkajax/hVhbp/

Resources