Pseudo Element Not Full Container Width When Border Used

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:

....


  1. 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:

    1. 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.
    2. 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



Leave a reply



Submit