How Can The Pseudo Element Detect The Height of The Non-Pseudo Element

width and height doesn't seem to work on :before pseudo-element

Note: The ::before and ::after pseudo-elements are actually laid display: inline; by default.

Change the display value to inline-block for the width & height to take effect while maintaining inline formatting context.

a.infolink::before {
content: '?';
display: inline-block;
background: blue;
color: white;
width: 20px;
height: 20px;
}

http://jsfiddle.net/C7rSa/3/

Why doesn't width/height work with non positioned pseudo elements?

First, it's not about percentage values. You will have the same result even with pixel values and both width and height aren't working.

Pseudo elements are inline elements and their width/height is only defined by their content and the width/height set with CSS will be ignored.

In CSS, ::before creates a pseudo-element that is the first child of the selected element. It is often used to add cosmetic content to an element with the content property. It is inline by default. ref

width

This property does not apply to non-replaced inline elements. The content width of a non-replaced inline element's boxes is that of the rendered content within them ref

The 'height' property does not apply. The height of the content area should be based on the font ... ref


By making the pseudo element position:absolute you will now consider the rules that applies to Absolutely positioned element in order to calculate width and height. You will also notice that the element will have a computed value of block within display.

Sample Image

You should also pay attention to the use of positioned element which means either relative, absolute, fixed or sticky BUT making the element position:relative will keep it an inline level element and you still cannot use width/height.

.positioned {
position: relative;
height: 15px;
background-color: aquamarine;
margin-bottom: 10px;
}
.positioned::before {
position: relative;
content: "";
background: red;
width: 80%;
height: 100%;
}

.not-positioned {
height: 15px;
background-color: aquamarine;
margin-bottom: 10px;
}
.not-positioned::before {
content: "";
background: red;
width: 80%;
height: 100%;
}
<div class="positioned"></div>
<div class="not-positioned"></div>

Stop pseudo elements from extending height of window

Just add overflow: hidden to your .angled-bottom. I would rather go with "contain: content", but that's not fully supported in Safari.

I also removed the bottom padding on said element.

:root {
--dark-purple: hsla(274, 64%, 10%, 1);
--med-purple: hsla(274, 45%, 20%, 1);
--light-purple: hsla(274, 45%, 35%, 1);
--lighter-purple: hsla(274, 45%, 40%, 1);
--light: hsla(274, 5%, 95%, 1);
--grey: hsla(274, 5%, 55%, 1);
--dark: hsla(274, 5%, 5%, 1);
--vertical-grad: linear-gradient(180deg, #ff8f3e, #cf132c, #420d6e);
--vertical-grad-r: linear-gradient(0deg, #ff8f3e, #cf132c, #420d6e);
--horizontal-grad: linear-gradient(90deg, #ff8f3e, #cf132c, #420d6e);
--horizontal-grad-r: linear-gradient(270deg, #ff8f3e, #cf132c, #420d6e);
}

body {
margin: 0;
z-index: -1;
margin: 0;
position: relative;
background-color: var(--dark-purple);
font-family: sans-serif;
font-size: 13pt;
color: var(--light);
}

.angled-top::before {
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
transform: skewY(-5deg) translateY(-5vw);
z-index: -1;
background: linear-gradient(220deg, var(--light-purple), var(--med-purple));
}

.angled-top {
display: flex;
padding: 2rem 4rem 9.5vw 4rem;
justify-content: center;
position: relative;
}

.angled-bottom::before {
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
transform: skewY(-5deg) translateY(5vw);
z-index: -1;
background: linear-gradient(220deg, var(--light-purple), var(--med-purple));
}

.angled-bottom {
display: flex;
padding: 9.5vw 4rem 2rem 4rem;
justify-content: space-around;
position: relative;

/* NEW */
overflow: hidden;
padding-bottom: 0;
}

.footer--column:nth-child(2) { transform: translate(0px, -2.5vw); }
.footer--column:nth-child(3) { transform: translate(0px, -5vw); }
<header>
<div class="angled-top">
[Header stuff here]
</div>
</header>

<main>
<div style="height: 70vh">... Simulate some large amount of content ...</div>
</main>

<footer>
<div class="angled-bottom">
<div class="footer--column">
<h3>Sitemap</h3>

</div>
<div class="footer--column">
<h3>Connect</h3>

</div>
<div class="footer--column">
<h3>Recommended Sites</h3>

</div>
</div>
</footer>

Why before pseudo element doesn't get 100% container height?

Seems to be working, it might be something else in your code:

.view-details:before {    content: "";    width: 1px;    margin: 0 20px;    border-left: solid 1px #cbcbcb;}
.view-details { display: inline-block; font-size:40pt;}
<div class="view-details"><a href="/retro-beauty-bar">VIEW DETAILS</a></div>

Make CSS pseudoelement :before same height as main element

Instead of height, rather use position: relative; for p, and position: absolute; for :before.

Js Fiddle

Here are the newly added CSS properties:

.editor p {
position: relative;
padding-left: 3.5em;

.editor p:before {
position: absolute;
top: 0;
bottom: 0;
left: 0;
}

Edit

It should be a second question :D

Pressing Enter in IE will not create a br, whereas in modern browsers it creates a br using :after. Here is to guarantee so that p tag does not remain empty:

Js Fiddle

.editor {
display: inline-block;
border: 1px black solid;
font-family: "Consolas", "Monaco", "Courier New", monospace;
counter-reset: line;
width: 90%;
height: 350px;
overflow: scroll;
padding-left: 0;
margin-left: 0;
z-index: 1;
}
.editor p {
display: block;
counter-increment: line;
background-color: #FFF;
text-align: left;
margin: 0px;
z-index: 2;
outline: none;
position: relative;
padding-left: 3.5em;
}
.editor p:before {
display: inline-block;
width: 2em;
height: 100%;
border-right: 1px black solid;
padding-right: 1em;
margin-right: 1em;
content: counter(line);
color: #FFF;
background-color: #006;
text-align: right;
position: absolute;
top: 0;
bottom: 0;
left: 0;
/*-webkit-user-select: none;
user-select: none;*/
}
.editor p:after {
content: " "
}
<div class="editor" contenteditable="true" spellcheck="false">
<p>Some paragraph</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas aliquet nunc non pulvinar luctus. Cras finibus turpis at arcu mollis, nec fermentum mi pretium. Aliquam suscipit lacus sapien, eu fringilla enim malesuada quis. Sed ut tincidunt erat.
In posuere vulputate venenatis. Mauris quis porta magna. Phasellus pharetra in nisl et luctus. Etiam in ultrices risus. Morbi vel dapibus ex. Suspendisse gravida libero non malesuada congue. Pellentesque ut nunc diam.</p>
<p>one</p>
<p>two</p>
<p>three</p>
</div>

Pseudo element ::after has no height

Try adding display: block; to :after.

By default pseudo elements are inline boxes

Get actual height of elements composited using :before and :after

You can use window.getComputedStyle to access the styles of the :before pseudo-element. See http://davidwalsh.name/pseudo-element . However, this gets the css height and width of the element, not the bounding box after the rotation transform.

Getting into hacky territory, I borrowed code from http://upshots.org/javascript/jquery-copy-style-copycss , copied all the styles from the pseudo element to an actual element, added it to the DOM and used getBoundingClientRect to get the bounding box.

var style = window.getComputedStyle(
document.querySelector(".arrow"), ":before"
)

var dest = {}
if (style.length) {
for (var i = 0, l = style.length; i < l; i++) {
prop = style[i];
camel = prop.replace(/\-([a-z])/, camelize);
val = style.getPropertyValue(prop);
dest[camel] = val;
}
} else {
for (prop in style) {
camel = prop.replace(/\-([a-z])/, camelize);
val = style.getPropertyValue(prop) || style[prop];
dest[camel] = val;
}
}

var copy = $("<div />").css(dest)
copy.appendTo(".arrow")
var boundingRect = copy[0].getBoundingClientRect()
console.log(boundingRect.height)
console.log(boundingRect.width)
copy.remove()

function camelize(a, b) {
return b.toUpperCase();
}

See http://jsfiddle.net/omahlama/mybzymp7/1/

Pseudo element reduces in size when elements around grow

Try this code:

.outter-wrapper {
width: 200px;
border: 1px solid black;
}

.wrapper {
display: inline-flex;
min-height: 1.5rem;
padding: 8px 24px 8px 0px;
width: 100%;
}

.input {
position: absolute;
z-index: -1;
visibility: hidden;
}

.label-wrapper {
line-height: 1.5rem;
position: absolute;
left: 10px;
}

.label {
position: relative;
margin-bottom: 0;
display: flex;
margin-left: 0;
margin-right: 24px;
flex-direction: row-reverse;
justify-content: space-between;
flex: 1;
align-items: center;
}

.label:before {
display: block;
min-width: 20px;
height: 20px;
content: "";
background-color: #fff;
border: 1px solid black;
border-radius: 4px;
position:absolute;
top:0;
}

.label:after {
position: absolute;
display: block;
height: 20px;
content: "";
background-repeat: no-repeat;
background-position: center center;
background-size: 80%;
}

input[type="checkbox"]:checked~.label::after {
background-image: url("https://cdn-icons-png.flaticon.com/512/447/447147.png");
width: 20px;
height: 20px;
top: 0;
}
<div class="outter-wrapper">  
<div class="wrapper">
<input class="input" name="checkbox2" id="checkbox2" type="checkbox">
<label class="label" for="checkbox2">
<div class="label-wrapper">
THis world is full of creatures
</div>
</label>
</div>
</div>


Related Topics



Leave a reply



Submit