Advance layout with pseudo classes - html

So the question is...
Good css rules:
We have to set top/right or bottom/right or top/left or bottom/left for position: absolute.
instead of margin...
But do we have to set thouse positions for css ::after or ::before??
Pseudo-classes always goes after or before the element.
If, so.. how to reach expecting output like that:
$(function(){
$('span').on('click',function(){
$(this).parent().append(' extra text ');
})
})
.test__block{
width:200px;
margin:20px;
border:2px solid;
position:relative;
}
#blue{
border-color:blue;}
#red{
border-color:red}
span{
cursor:pointer;
font-weight:800}
#blue:after {
content: "+";
font-size:16px;
position: absolute;
margin-left: 0;
margin-top: -4px;
color:orange;
}
#red:after {
content: "+";
font-size:16px;
position: absolute;
left: 80px;
top: 30px;
color:orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='blue' class='test__block'>Blue text with after element, position set to absolute and top/left, <span>add</span></div>
<div id='red' class='test__block'>Red text with after element, position set to absolute and margin, <span>add</span></div>
So, if you press add button you will see how '+' react with component.
Expecting effect is a blue container.
So what is a propper way to do that? It is only a example. The thing is i will not add text but text will have diferent dimension on each component, so adding different position to after element each time will be pointless? or maybe someday content will change and i will have to set thouse each time?
What if i will have to set thouse for 100? or 1 000 comonents?
Any clue?!

::after is a pseudo element which allows you to insert content onto a page from CSS (without it needing to be in the HTML). While the end result is not actually in the DOM, it appears on the page as if it is.
::before is exactly the same only it inserts the content before any other content in the HTML instead of after. The only reasons to use one over the other are:
You want the generated content to come before the element content,
positionally.
The ::after content is also "after" in source-order, so it will
position on top of ::before if stacked on top of each other naturally.
The other thing you concern about is the position of it. Try to make $(this).parent().append(' extra text '); to $(this).parent().append(' extra text extra text extra text extra text extra text');. The + will remain in the same position (according to blue one) and if you click add, it will still be the end of the text. Because when you set margin-left and margin-top values to blue one, you are setting the positions of + on span.
So when you're adding the text to that span element and click add, the text will expand and the + will always come ::AFTER the text with given positions, no matter what. Because of pseudo classes. The vertical and horizontal positions you set on ::after is the position of after the element.
An absolutely positioned element is an element whose computed position value is absolute or fixed. The top, right, bottom, and left properties specify offsets from the edges of the element's containing block. (The containing block is the ancestor relative to which the element is positioned.) If the element has margins, they are added to the offset.
Hope it helps :)

You can apply the same position declarations to a pseudo-element as you can to an element:
position: static
position: relative
position: absolute
position: fixed
position: sticky
On the whole, in order to establish complete control over your positioning of the pseudo-element I would suggest it is good practice to apply position: relative to the parent element (if it doesn't already have a non-static position declaration applied to it) and then apply position: absolute and co-ordinates to the child pseudo-element.

Related

If Inline box is relative positioning, then what is its block-level box affected by?

source spec: Anonymous block boxes.
I'm confused about this sentence.
When such an inline box is affected by relative positioning, any resulting translation also affects the block-level box contained in the inline box.
I don't know whether the "relative positioning" is the general meaning, I mean it can be absolute or fixed, and other properties of display, e.g, inline-block.
Let's see examples.
I know DIV broke the line box, but position: relative seems useless, I can remove it directly.
.father {
position: relative;
border: 1px solid red;
}
<span class="father">
<div>Hi Wick</div>
</span>
But, If I modified relative to absolute, I knew the line box wasn't "broke", so border worked normally. If I added the inline-block property of display, the result is the same.
.father {
position: absolute;
border: 1px solid red;
}
<span class="father">
<div>Hi Wick</div>
</span>
Also, what does any resulting translation mean? I know some behaviors may change containing block, so they will be affected by their descendants. I'm not sure whether it is about the containing block.
Therefore, I need some examples!
A <span> element is inline, which means it has no "box" around it to apply a border to. It's treated the same as a line of text with no container. Imagine it as a horizontal line where the center of each letter inside it is placed on that line. Applying position: absolute; to a <span> causes it to be treated the same as if it was display: block;, which is why the border property works on it then.
In your first example, the inner div is a block level element inside an inline element. If you applied a border to the div, you'd see it stretches across the width of the container to fill the space horizontally. Since the parent span is inline, the border doesn't show like you want it to, but the height of the child div at least gives some level of "size" to the span, if only vertically.
Also, "any resulting translations" just refers to CSS properties that move the element on the screen, such as left, right, top, bottom, or transform: translate();.

Why button is overlapping with div?

I have a main wrapper div with a content div and a button. The button is supposed to go underneath the content div but for some reason it's overlapping with it.
The content div has css:
#groupMembers {
position: absolute;
height: 50%;
width: 90%;
left: 5%;
overflow: scroll;
display: inline-block;
}
and the button has:
button {
display: inline-block;
width: 70%;
left: 15%;
}
I thought since they're both inline-block that they wouldn't overlap, but for some reason they are. I made a JsFiddle to show: http://jsfiddle.net/b5hp6boz/
Can anybody help me get the button to display beneath the content div?
Remove the (extensive) use of absolute positioning.... Change it to position: relative; if necessary. But on many elements even that is not necessary.
Move the button div up to under the <h4>add members</h4> in the HTML where you appear to want it.
Then adjust margins for #DIV_05 and the button.
Fiddle Update or Fiddle Update 2
(Note I merely performed a search to change absolute to relative in your CSS, then adjusted from there.)
By using absolute positioning so extensively you were forcing elements into unnatural positions. Then when it wasn't working out.. you are left wondering why. Let things fall where they naturally want to fall. Change the HTML for overall render order, don't force things with absolute positioning.
Use of absolute position is most commonly used to adjust z-index and make elements not alter positioning of other elements. (like a global float of sorts) It should not be the fall back for positioning everything in any layout.
The problem in your code is that you have given the #DIV_5 the following CSS:
position: absolute;
By giving a HTML element an absolute position it is removed from the normal rendering process by not obtaining any space in the document. That means it is not affecting the position of the following BUTTON_105 element. That's why the button is positioned right underneath the H4_4 element (which is the first element not having an absolute position).
To fix that simply remove the position: absolute; declaration for #DIV_5. (Btw: You should try not to make heavy use of absolute positioning as it can cause further issues.)
Try giving your div tag a higher z-index value.

How can I force text to ignore other elements?

I have a project that hides and shows elements using the visibility parameter. Another element is pushing the text in these elements down and I need to know if there is a way to force the text back to the top of its element. I have tried different display parameters, floats, etc and haven't found anything (other than absolute position) that will work. The problem with absolute positioning is that the container div will then hide overflow instead of expanding with the content. JSFiddle
check JSFiddle for example and code
The problem you are having is the relative position of the list:
#list {
position: relative;
left: -25%;
}
If you switch to using margin-left instead of left, you get the layout you want:
#list {
margin-left: -25%;
}
http://jsfiddle.net/TL969/2/
With relative positioning, surrounding elements are not affected by adjustments. Surrounding elements are layed out as though no adjustments were made to the positioning. By positioning it with negative margin instead, surrounding elements are affected, and thus you free up room for the text.

DIV changed its behaviour when "position:absolute" was added to it. Why?

I'm new to CSS and I have a question.
First, my HTML and CSS code:
<!-- HTML CODE -->
<body>
<div id="container">Container
</div>
<div id="inner">Inner</div>
</body>
<!-- CSS CODE -->
#container {
background-color:#b6ff00;
width:500px;
height:500px;
position:relative;
}
#inner {
background-color:#ffd800;
}
With current code, the browser shows the following page:
This is expected.
But if I add this css property to #inner element position:absolute; there will be a following output:
As you can see, the #inner div, takes only that much space it needs. Why this changed with only position:absolute; property added to #inner div?
That's because when you use position: absolute; the element will take up width upto the elements defined/content it contains., cuz it just gets out of the document flow so it is block level in nature but won't take up entire horizontal space on the document, as it's just out of the flow of the document..
If you want it to be full width you need to define width: 100%; explicitly so that it will take 100% of the relative parent's width as well as the height if you declare height: 100%;
Also, make sure you always use position: absolute; with a wrapper element set to position: relative; or your element will fly out in the wild which will eventually end up taking the viewport as the last relative wrapper if you set the position of the element using top, right, bottom or left.
I've explained here in detail, that how CSS Positioning Works
Worth to note that, you make any element a position: absolute; element, it will behave as a block level element, but you need to define height and width so for example, if you turn an inline span element a position: absolute; you can define height and width without making it display: block; (Unless and until you are using display: none; initially)
position: absolute; does not behave the same as block elements.
You will need to set a width and a height for a div that is absolutely positioned.
This is fundamentally how position absolute works. Once taken out of the flow of the document it becomes an inline-block element that is absolutely positioned within the nearest element that is positioned relatively (or the top most element)
If you need it to then be a certain dimensions you can try to set widths and heights, or you can do things like
#inner {
position: absolute;
left: 0;
right: 0;
}
...which would ensure it always stuck to the left and right sides of the screen.
It's generally good practice to put things that are positioned absolutely inside of an element with "position:relative" on it, as your code stands it suggests you want your #inner element to be placed anywhere on the page, whereas if you wanted it to be of a size and position relative to #container your code should look like this:
<body>
<div id="container">
Container
<div id="inner">Inner</div>
</div>
</body>
with CSS such as:
#container {
position: relative;
}
#inner {
background-color:#ffd800; width:500px;
height:500px;
position:relative;
}
You can see your output here:-
http://jsfiddle.net/KggJd/
Let me explain a little:
Postition: relative
This will align itself in accordance with the elements found before (i.e) Prior Siblings.
You can change the position by using margin-top, margin-left, ....
Position: absolute
This will always consider from the browser's start point and won't be in accordance with anything.
Drawbacks:
You cannot consider this as the parent or anything when absolutely positioned.
You can change its position by using top, bottom, right, left.

Why do absolute elements stack up on each other instead of stacking one after the other?

How can get both #row1 and #row2 in the following code to be visible, one after the other vertically, as if there wasn't any absolute/relative positioning involved (though without removing the positioning properties)? I.e. having the two .row <div> to appear as "normal" block elements.
body { position:relative; min-height: 2em; width: 100%; }
.container {position:absolute;}
.row {position:relative;}
.col1, .col2 {position: absolute;}
<body>
<div class="container">
<div id="row1" class="row">
<div class="col1">Hello</div>
<div class="col2">World</div>
</div>
<div id="row2" class="row">
<div class="col1">Salut</div>
<div class="col2">le monde</div>
</div>
</div>
</body>
(Sample also available as a fiddle.)
I need the elements to have the positioning provided in the CSS rules, for reasons excluded here.
The content is programmatically dynamic; I don't know the elements' heights beforehand, so a solution can't be based on specifying an absolute length (e.g. 'px') anywhere.
Well you have some weird wishes here so let me explain you what those positions really mean in CSS and how they work, using position: relative; is just like using static position, the difference is making an element position: relative;, you will be able to use top, right, bottom and left properties, though the element will move, but physically it will be in the document flow..
Coming to position: absolute;, when you make any element position: absolute;, it gets out of the document flow, hence, it has nothing to do with any other element, so in your example
you have .col1, .col2 {position: absolute;} which are positioned absolute and since both are out of the document flow, they will overlap... Because they are already nested under position: absolute; parent i.e .container and since no width is assigned, it will take the minimal width and hence, your elements overlap, if you cannot change your CSS(which according to me doesn't make any sense why you can't change) still if you want, than you can do is this..
Demo (Without removing any of your position property) And this is really dirty
For the s characters, it will be at the top as your container element is out of the flow, and hence, no height will be considered in the document flow, unless and until you wrap that s in some element, and bring it down with, margin padding or CSS Positioning.
CSS Positions Explained
As I commented, here are few examples of how CSS Positioning actually works, to start with, there are 4 values for position property i.e static which is the default one, relative, absolute and fixed, so starting with static, nothing to learn much here, elements just stackup one below the other unless they are floated or made display: inline-block. With static positioning, top, right, bottom and left won't work.
Demo
Coming to position: relative; I've already explained you in general, it's nothing but same as static, it stacks up on other element, it is in the document flow, but you can tweak the elements position using top, right, bottom and left, physically, the element stays in the flow, only position of the element is changed.
Demo 2
Now comes absolute which generally many fails to understand, when making an element absolute it gets out of the document flow, and hence it stays independent, it has nothing to do with other elements positioning unless it's overlapped by other position: absolute element which can be fixed using z-index to change the stack level. The main thing to remember here is to have a position: relative; container so that your absolute positioned element is relative to that relative positioned element, else your element will fly out in the wild.
It's worth noting that position: absolute; element when positioned absolute; inside an absolute positioned parent element, than it is relative to that element and not relative to the grand parent element which may be positioned relative
Demo 3 (Without position: relative; container)
Demo 4 (With position: relative; container)
Last is position fixed, this is same as absolute but it flows along when you scroll, it's out of the document flow, but it scrolls, also, position: fixed; element cannot be relative to any container element having any type of position, not even relative, position fixed element is always relative to the viewport, so designers use position: absolute; when they want to have a fixed position behavior but relative to parent and tweak the top property onScroll.
Demo 5
What you want, is not possible without modifying the CSS position property. However, what you can do without touching the existing CSS, is overriding it with a more specific selector
.row .col1, .row .col2 {
position: relative;
}
See JSFiddle
when position:relative is used, the page layout will occur normally before being offset by top, left values, however position:absolute will ignore the document flow. The relative ones will work with no changes but absolute must be changed
.col1, .col2 {display:inline-block;}
http://jsfiddle.net/C4bQN/
EDIT: Depending on your circumstances, maybe you can wrap your table in an absolute positioned div then use normal document flow within the table?
<div class="absolute-wrap">
<div class="row">
<div class="col"> </div>
</div>
</div>