Pseudo element not full container width when border used
From the specification
The position and size of an element's box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element. The containing block of an element is defined as follows:
....
- If the element has 'position: absolute', the containing block is established by the nearest ancestor with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:
- In the case that the ancestor is an inline element, the containing block is the bounding box around the padding boxes of the first and the last inline boxes generated for that element. In CSS 2.1, if the inline element is split across multiple lines, the containing block is undefined.
- Otherwise, the containing block is formed by the padding edge of the ancestor
Then
The padding edge surrounds the box padding. If the padding has 0 width, the padding edge is the same as the content edge. The four padding edges define the box's padding box.
This explain why your element doesn't use the border-box as reference but the padding-box when positionned. It's also the same for percentage width1. using width:100%
means the padding and the content of the containing block. Border aren't counted.
Concerning box-sizing
... , any padding or border specified on the element is laid out and drawn inside this specified width and height.
So the border need to belong to the element not a parent element in order to consider box-sizing
which is not your case since the border isn't applied to the pseudo element:
1 For absolutely positioned elements whose containing block is based on a block container element, the percentage is calculated with respect to the width of the padding box of that element.ref
.box { border:5px solid; padding:10px; background:red; min-height:100px; position:relative;}span:first-child { display:inline-block; width:100%; background:blue;}span:last-child { position:absolute; bottom:0; left:0; width:100%; background:green;}
<div class="box"> <span>I am a static element</span> <span>I am a absolute element</span></div>
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 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>
:before pseudo-element on container has a white border
This is common antialiasing issue in Chrome caused by CSS transforms, add -webkit-backface-visibility: hidden;
to your :after
and :before
elements.
Setting the border-width of a :after pseudo-element based on the parent element's width
I think Scott is right on the money when he says:
CSS does not allow percentage values to generate border widths (which would be ideal in this situation.
Since you have this tagged "jquery", I assume you're open to jquery solutions? I'm afraid this may not be possible with just CSS, using the border/triangle trick. Of course javascript opens this is up to a ton of possible solutions, here's one:
Demo: http://jsfiddle.net/bcAQc/2/
$('a').each(function(){
var self = $(this),
width = (self.width() / 2) + 10; // +10 for <a> padding
self.append('<span class="triangle" />');
$('.triangle', self).css({
'border-left-width' : width,
'border-right-width' : width
});
});
.triangle {
position: absolute;
border: 40px solid transparent;
border-top-color: blue;
display:block;
top:20px;
left: 0;
}
Although this seems to do what you want, I find the different angles in the demo make it look kind of ugly. If it was me, I would consider fixed-width list items: it would make this totally possible with just CSS and IMO would look a lot nicer.
Pseudo Element 100% width is not taking container size
the problem is you are using position:absolute
From MDN
Absolute positioning
Elements that are positioned relatively are still considered to be in
the normal flow of elements in the document. In contrast, an element
that is positioned absolutely is taken out of the flow and thus takes
up no space when placing other elements. The absolutely positioned
element is positioned relative to nearest positioned ancestor. If a
positioned ancestor doesn't exist, the initial container is used
A fix is to add this to your CSS:
.articleWrapper {
position:relative;
}
and change top:0;
in .articleWrapper:before
to any negative value you like best.
here is a snippet
#singleWrapper { margin: auto; max-width: 1100px;}.single #singleWrapper { margin: auto; max-width: 1100px; /*box-shadow: inset 0 650px rgba(0,0,0,0.30);*/ position: relative; overflow: hidden;}#leftColumn .content-area { padding-right: 310px; width: 100%;}.articleWrapper { position:relative;}.articleWrapper:before { content: ""; position: absolute; top: -30%; left: 0; background: #009cff; background: linear-gradient(to right, #1d0027, #935cd2, #1d0027); height: 2px; width: 100%;}#leftColumn .content-area #main { background: #000; background: rgba(0, 0, 0, 0.30); padding-left: 20px; padding-right: 20px;}#singleWrapper .contentHolder { margin-right: -310px; width: 100%; float: left; position: relative;}#rightColumn { float: right; position: relative; display: block; width: 290px;}#leftColumn,#rightColumn { display: inline-block; vertical-align: top; margin-top: 1.1em;}
<div id="singleWrapper"> <div id="leftColumn" class="contentHolder"> <div id="primary" class="content-area"> <main id="main" class="site-main" role="main"> <div class="articleWrapper"> <h1>Title</h1> <div class="articleBody"> Article Body </div> </div> </main> </div> </div> <div id="rightColumn"> Side Bar Area </div></div>
::after pseudo-element width is different of content
Absolute positioning width does not take account of borders...that's the issue.
So you will have to adjust accordingly
calc
is a good option here.
div { width: 200px; border-width: 0 10px 0; border-style: solid; border-color: red; height: 200px; margin: 3em auto; position: relative;}
div::after { content: ""; width: 100%; width: calc(100% + 20px); /* 2 x 10px */ height: 2em; position: absolute; bottom: 100%; background: pink; left: -10px; /* 1x border-width */}
<div></div>
1px wide element looks thicker than a border of 1px width
It only looks thicker due to the pixelation from being diagonal. In the snippet, hover the first box you will see the lines rotate and appear as thick as the border.
In the second box I have come up with a bit of a workaround. The width of the diagonal lines is halved (0.5) of the default. And then using box shadow, I add back a quarter (0.25) to each side of the box using spread, and then a little anti-alias hack by using blur. This is fix:height: calc(var(--borderThickness) * .5 );
box-shadow: 0 0 .075px calc(var(--borderThickness) * .25 ) currentColor;
On 100% zoom, this will make the line appear a little thinner. On higher zooms it will basically match the width because the '0.075px' box-shadow blur becomes negligible
:root { --borderThickness: 1px }
.boxes { display: flex; gap: 1rem; justify-content: center }
.box {
border: var(--borderThickness) solid currentColor;
display: grid;
height: 100px; width: 100px;
overflow: hidden;
place-items: center;
position: relative;
}
.box::before, .box::after {
background-color: currentColor;
content: '';
grid-area: 1/1/-1/-1;
height: var(--borderThickness); width: 141.4%;
transform: rotate(var(--rotate));
transition: transform 120ms ease-in-out;
}
.box::before { --rotate: 45deg } .box:hover::before { --rotate: 90deg }
.box::after { --rotate: -45deg } .box:hover::after { --rotate: 0deg }
.box.fix::before, .box.fix::after {
height: calc(var(--borderThickness) * .5 );
box-shadow: 0 0 .075px calc(var(--borderThickness) * .25 ) currentColor; /* Thicken line and anti alias */
}
<div class="boxes">
<div class="box"></div>
<div class="box fix"></div>
</div>
Related Topics
Adjusting and Image Size to Fit a Div with Bootstrap
HTML5 Input for Money/Currency
How to Color Table Columns Using CSS Without Coloring Individual Cells
What Is Dom? (Summary and Importance)
How to Vertical Align an Inline-Block in a Line of Text
CSS Vertically Align Floating Divs
Pseudo Elements Breaking Justify-Content: Space-Between in Flexbox Layout
Center <Img/> Inside a <Div> with CSS
Stop Floating Divs from Wrapping
Open Local Files(File://) Using Chrome
Can an HTML Email Body Reference a File Sent as an Attachment (In The Same Email)
Controlling The Size of an Image Within a CSS Grid Layout
How to Make a Div Take The Full Width of The Page When It Is Inside Another Div That Have 90% Width