CSS3 Columns and pseudo element positioning - css

I've got a page with CSS3 columns, and I am trying to place a pseudo element at the same Y position as the inline element, but at a fixed X position (in the left margin). This works great on the first column, but the rest of these pseudo elements in the other columns do not behave properly.
What ends up happening is that the pseudo elements are placed along the left margin, where the element would be if it were in a single column. If you scroll down you will see the green blocks along the left where the text would be if it were in a single column.
What I'd like is for the green blocks to be in the column gap area at the left edge of the line of text where the exists.
I'm guessing the issue is with this bit of code:
.marker:after {
content: ' ';
display: block;
white-space: nowrap;
position: absolute;
left: 0px;
width: 0;
height: 0;
border: 6px solid green;
}
JSFiddle: http://jsfiddle.net/o0xu0e2x/1/
Note: My application only requires Chromium 41+ support, so that is why I am using -webkit tags. Using pseudo element :before/:after does not matter, they both behave this way.

You need to relatively position the parent .section elements.
In doing so, the absolutely positioned pseudo elements are positioned relative to the .section elements rather than the window.
Updated Example
.section {
position: relative;
}

Related

Keep element position fixed to parent using transform on scroll

I understand it's possible to position:fixed a child element relative to it's parent using transform. When scrolling the document, is it possible to keep the fixed child's position relative to it's parent, rather than the document?
Demo
https://jsfiddle.net/ds0vbtbt/3/
Update: Above is a simiplied version of my problem. position:absolute: is not the solution I'm looking for.
Update:
Doesn't seem possible without JS once the initial transform is performed
Yeah you can do that with position absolute, provided the containing element is set to relative. You don't need the transform property at all.
.test {
width: 400px;
height: 400px;
border: 1px solid;
position: relative;
}
.box {
margin-top: 20px;
width: 300px;
height: 100px;
border: 1px solid red;
position: absolute;
}
Updated fiddle: https://jsfiddle.net/ds0vbtbt/1/
An element with position: absolute; is positioned relative to the nearest positioned ancestor (instead of positioned relative to the viewport, like fixed).
However; if an absolute positioned element has no positioned ancestors, it uses the document body, and moves along with page scrolling.
Update: position: fixed is always going to relative to the view-port - so if you change the window size it will be updated, but when scrolling it wont be. That said, Elements with transforms act as a containing block for fixed position descendants, so position:fixed under something with a transform no longer has fixed behavior. They do work when applied to the same element; the element will be positioned as fixed, and then transformed.
You are using position:fixed which fix the element with viewport.
Use position:absolute for child element to fix it with parent element.

How is 'relative' positioning placing the tooltip at the correct position?

Here's an example of a CSS tooltip. The author positions the toolip relatively.
.tooltip{
display: inline;
position: relative;
}
However, the tutorial says,
Relative. This type of positioning is probably the most confusing and
misused. What it really means is "relative to itself". If you set
position: relative; on an element but no other positioning attributes
(top, left, bottom or right), it will no effect on it's positioning at
all, it will be exactly as it would be if you left it as position:
static; But if you DO give it some other positioning attribute, say,
top: 10px;, it will shift it's position 10 pixels DOWN from where it
would NORMALLY be. I'm sure you can imagine, the ability to shift an
element around based on it's regular position is pretty useful. I find
myself using this to line up form elements many times that have a
tendency to not want to line up how I want them to.
There are two
other things that happen when you set position: relative; on an
element that you should be aware of. One is that it introduces the
ability to use z-index on that element, which doesn't really work with
statically positioned elements. Even if you don't set a z-index value,
this element will now appear on top of any other statically positioned
element. You can't fight it by setting a higher z-index value on a
statically positioned element. The other thing that happens is it
limits the scope of absolutely positioned child elements. Any element
that is a child of the relatively positioned element can be absolutely
positioned within that block. This brings up some powerful
opportunities which I talk about here.
What I understand is that, without modifiers like top, left etc. relative is equivalent to static and goes with the flow of the page. Then how's the tooltip being displayed at the correct position, i.e. above the hyperlink? Shouldn't it appear at the end of the page instead?
The CSS you provided for tooltip is not complete. I think you saw it in w3schools. But note that there are two elements for it: a parent element with .tooltip class and a child element (actual tooltip text) inside it with .tooltiptext class.
the parent element has position: relative without any top, left ... positions which acts as you said as a static element in its original (normal) place. But the child tooltiptext inside it has a position: absolute which is why it is seperated from normal text flow and put over them.
Here is a sample:
.tooltip {
/* this is just to add meaning for position:absolute of .tooltiptext */
position: relative;
color: navy;
}
.tooltip .tooltiptext {
/* Position the tooltip */
position: absolute;
z-index: 1;
top: 100%;
left: 10%;
/* style the tooltip */
min-width: 50px;
background-color: #ff9;
color: black;
font-size: 10pt;
border-radius: 3px;
padding: 3px 10px 6px;
white-space: nowrap;
visibility: hidden;
}
.tooltip:hover .tooltiptext {
visibility: visible;
}
<span>Sample: </span>
<span class="tooltip">Hover over me
<span class="tooltiptext">Tooltip text</span>
</span>

css-prop outline on DIV element not showing or incorrect

i came up with this while i was looking for another fault..
Strange things are happening..
.blok {
outline: 1px solid red;
}
.blok > label {
padding-top: 7px;
margin-bottom: 0;
text-align: right;
width: 41.66666667%;
float: left;
outline: 1px solid green;
}
.blok > div {
outline: 1px solid yellow;
height: 50px;
}
<div class="blok">
<label>
Deep in the night
</label>
<div>
I was looking for some fun
</div>
</div>
about .blok > div : outline
In Chrome & Safari i get none outline at all..
In Firefox i have the parents outline overwritten..
I'm looking for why this is happening..
I know i can use display: inline-block; on div > div
i know this looks like a really stupid question because i know the solution to the problem for a situation that is rare.. but it is important for me know what and who is wrong..
Thanks in advance!
This is occurring because the margins are collapsing.
In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.
When two or more margins collapse, the resulting margin width is the
maximum of the collapsing margins' widths. In the case of negative
margins, the maximum of the absolute values of the negative adjoining
margins is deducted from the maximum of the positive adjoining
margins. If there are no positive margins, the maximum of the absolute
values of the adjoining margins is deducted from zero.
Look at Updated jsFiddle working fine now.
.blok > div {
outline: 1px solid yellow;
height: 50px;
overflow: hidden; /* this line added */
float: left; /* this line added */
}
Margins of elements that establish new block formatting contexts (such
as floats and elements with 'overflow' other than 'visible') do not
collapse with their in-flow children.
The most important thing about an outline is "The outline is NOT a part of an element's dimensions". [http://www.w3schools.com/css/css_outline.asp]
As a div is a block level element, the dimensions of the inner div and the dimensions of the outer div are identical. The outline of the inner div and outer therefore are displayed in the same visual space, where in webkit based browsers the parent's outline is showing, and in gecko (firefox) browser the child's outline shows.
Looking at the stacking spec (http://www.w3.org/TR/CSS21/zindex.html#outlines). The difference in implementation arises from E.2 7.2.2 and E.2 10, causing the difference in behaviour. Where in this case, from what I understand, Gecko based browsers E.2 7.2.2, and webkit follows E.2 10.

Absolute positioned item in a flex container still gets considered as item in IE & Firefox

If I have multiple elements with the property justify-content: space-between in a flex container and I want to absolute position one of them and remove from the flex flow, as showed here:
This works in Chrome but not in IE and Firefox as the absolute positioned element is considered as 0 width, but still in the flex flow:
Is there a fix to this keeping the layout as it is?
CodePen
It turns out that all it takes is three simple steps
(Demo)
1). Set the left and right margin to auto on each child
img {
margin-left: auto;
margin-right: auto;
}
2). Set the left margin on the first child to 0
img:nth-child(2) {
margin-left: 0;
}
3). Set the right margin on the last child to 0
img:last-child {
margin-right: 0;
}
If you miss any of these steps it will not work properly
This works in firefox and chrome, I haven't tested it in any other browsers.
EDIT:
Thanks to #Pontiacks
Apparently you can get away with adding margin-left: auto to the img:nth-child(2)
updated jsfiddle
I have a much simpler hack to solve this particular problem.
div {
background-color: #66BB66;
display: flex;
position: fixed;
width: 100%;
justify-content: space-between;
}
div > img:nth-child(2) {
position: absolute;
left: 0;
}
<div>
<img src="http://www.fillmurray.com/150/150">
<img src="http://www.fillmurray.com/150/100">
<img src="http://www.fillmurray.com/150/150">
</div>
Just change the order in the DOM. The absolutely positioned element is still positioned wherever you put it, and although flexbox still treats it like it is in the flow, its position in the flow (in the dom) causes flexbox to allocate space the same way across browsers.
I believe you could use the order property to achieve the same thing.
I found that none of these handled my case, as I have three elements I want to have evenly spaced, and one absolutely positioned sibling. I found the trick in this case is just to add margin-right: auto to the first element to be evenly spaced, and margin-left: auto to the last element to be evenly spaced. You can check it out at this fiddle http://jsfiddle.net/tch6y99d/

In CSS, is it possible to select the last element before a wrap?

For example,
I have a bunch of div's side by side, and each div has a border-right:1px
The parent element is a certain width so at a certain point, the extra div wraps to the next line.
In essence, I do NOT want a border-right for the last div before the wrap.
If this doesn't make sense, I can create a fiddle. I just want to know can I target that last div before the wrap. (last-child will target the last div that is on the next line which isn't want.)
Figure out how many columns you're getting with the current width, either hardcoded or with JS and then use the nth-child selector.
For example if you have 3 columns per row with each div having a class of col it would be
div.col:nth-child(3n){border-right:none;}
The nth-child selector can be modified depending on however many columns are in each row of divs.
There is no way to select the last item from multiple lines, only the :last-child.
If your elements line up in columns, the multi-column module may be of interest to you. It has a column-rule property that's similar to borders, but only appears vertically between columns, never on the outer edges.
http://cssdeck.com/labs/febtiiet
.container {
columns: 20em;
column-rule: 1px solid;
}
Prefixes may be required: http://caniuse.com/#feat=multicolumn
Otherwise, you will need to switch to placing the border on the left as MrLister suggests:
http://cssdeck.com/labs/f8qjngd4
.container {
overflow: hidden;
padding: 0;
border-style: none;
}
.child {
border-left: 1px solid;
position: relative;
left: -1px;
display: inline-block;
width: 20em;
}

Resources