Can I use css to always keep element as first child - css

I have a div with elements that may dynamically get added and removed. Is it possible to define a css class that makes sure that the corresponding element is always displayed as the first child of the div (i.e. on top)
Or do I need to attach an on change event listener to the div to move the child to the top via js?

You can use display: flex on the parent, then use the order attribute on the child to put it where you want.
ul {
display: flex;
flex-direction: column;
}
.first {
order: -1;
}
<ul>
<li>asdf</li>
<li>asdf</li>
<li class="first">first</li>
</ul>

here's the fix:
HTML
<div>
<p>Must not be first 1</p>
<p>Must not be first 2</p>
<p class="first">Must be first</p>
<p>Must not be first 3</p>
</div>
CSS
div {
display:flex;
flex-flow:column wrap;
}
.first {
order:-1;
}
https://jsfiddle.net/rp1m8874/

It's a bit hacky, but you can add a class to the one that needs to stay first and then set position: absolute; top: 0 on it. You'll have to push all other elements down by the first one's height though.
.container {
position: relative;
}
.container div {
position: relative;
top: 15px;
height: 15px;
}
.container div.first {
position: absolute;
top: 0;
}
<div class="container">
<div>
another div
</div>
<div class="first">
I should be first
</div>
<div>
another div
</div>
</div>

Yes if you are using Jquery :
$("#yourContainer").prepend("<div>This div will be first!</div>");

Related

CSS: How to move a div above another another one?

I have two div, A and B. I would like to put element B above element A using CSS.
I can warp them in a parent div if it's needed.
I have tried several things (float, vertical-align), without success.
What I have:
A
B
What I want:
B
A
Any idea?
Thanks
You can do this with order attribute, whenever you assign a flex display to the parent element.
So in order to do this, you just have to create two div and wrap them within a parent, then make your parent display as flex by then, children of that parent will follow the flex rules. One of the available attributes for flex items is order which you can define for each of the children and gave them sequence number (1, 2, 3, ...) then the child with the lower value will appear first and so on.
.container{
display: flex;
flex-direction: column;
}
.first {
order: 2;
}
.second {
order: 1;
}
<div class="container">
<div class="first">A</div>
<div class="second">B</div>
</div>
Try this with the 2 text divs in a container
body {
font: 400 16px/1.5 sans-serif;
}
.text-wrap {
position: relative;
}
.text-1 {
position: absolute;
top: 1.5em; /* same as line-height */
}
.text-2 {
position: absolute;
top: 0;
}
<div class="text-wrap">
<div class="text-1">
AAA
</div>
<div class="text-2">
BBB
</div>
</div>
.container{
display:flex;
flex-direction: column-reverse;
}
.child{
width: 50px;
height: 50px;
background-color:red;
margin: 10px;
}
<div class="container">
<div class="child">a</div>
<div class="child">b</div>
</div>
Using flex-direction you can move the children of a container

Align scroll down arrow to the bottom center of a full-screen div in WPBakery Visual Composer

I have a series of full-screen divs in Visual Composer and I want an arrow at the bottom of each one indicating to users they should scroll for more content. I tried absolute positioning on the divs containing the icon with no luck. All I've done is move the icon a few pixels to th
<section class="l-section wpb_row height_full valign_center width_full with_img" id="home">
<div class="l-section-img loaded" data-img-width="1920" data-img-height="809">
</div>
<div class="l-section-h i-cf">
<div class="g-cols vc_row type_default valign_top">
<div class="vc_col-sm-12 wpb_column vc_column_container">
<div class="vc_column-inner">
<div class="wpb_wrapper">
<div class="w-image align_center" id="mainlogo">
<div class="w-image-h"><img src="logo.png" class="attachment-full size-full">
</div>
</div>
<div class="ult-just-icon-wrapper">
<div class="align-icon" style="text-align:center;">
<a class="aio-tooltip" href="#whatis">
<div class="aio-icon none " style="display:inline-block;">
<i class="Defaults-chevron-down"></i>
</div>
</a>
</div></div></div></div></div></div></div>
</section>
Existing CSS:
.aio-icon.none {
display: inline-block;
}
.aio-tooltip {
display: inline-block;
width: auto;
max-width: 100%;
}
.vc_column-inner {
display: flex;
flex-direction: column;
flex-grow: 1;
flex-shrink: 0;
}
.wpb_column {
position: relative;
}
.vc_column_container {
display: flex;
flex-direction: column;
}
.vc_row {
position: relative;
}
.l-section-h {
position: relative;
margin: 0 auto;
width: 100%;
}
The icon itself is the Defaults-chevron-down.
Do you have an idea how to position that icon properly?
I also struggled a little with this. But there is a rather quick and dirty fix for this:
Just put another row below the full height row. Place your icon there and give this element a top margin of i.e. -200px.
For some strange reason the rather logical approach to put the icon in the full height row itself and to position it absolute to the bottom is not properly supported by the source generated from WPB.
I had this issue this week. The way I resolved it was added the icon in that row/section (in my case a single image element with a custom link to a .svg) and added a class to it.
The CSS for the class was then:
position:absolute;
margin-left: auto;
margin-right: auto;
left: 0;
right: 0;
text-align: center;
margin-top:-30px;
(I added a negative margin top as I noticed the icon was cutting of a little on my Google Pixel phone with the fixed bottom bar so that pulled it up a little.)

Make an element take up available horizontal space without causing its parent to widen

I have a flexbox container with exactly two children, both of which can have variable content. I want the width of the entire container to fit the width of the first child, but I want the second child's contents to wrap and not cause the container to grow horizontally. See the runnable snippet below for a visual problem description.
Currently looking for a CSS Grid solution. I have found one partial solution, but relies on JavaScript: Make the second child a relative container, put its contents in an intermediate absolutely-positioned container, and use JS to set a fixed height. At least it's good for showing what I'm looking for.
Problem:
.container {
display: inline-flex;
flex-direction: column;
border: 1px solid red;
}
.child {
background-color: wheat;
margin: 5px;
}
<div class="container">
<div class="first child">
This content can grow and be as wide as it wants
</div>
<div class="second child">
This content will also be any size it wants, but I * want it to wrap at the asterisk in this sentence, which is where the first child above would naturally end. This will be its own flexbox container holding several buttons that should wrap onto new rows.
</div>
</div>
JavaScript/absolute solution:
let second = document.getElementsByClassName('second')[0]
let content = document.getElementsByClassName('absolute')[0]
second.style.height = content.offsetHeight + 'px'
.container {
display: inline-flex;
flex-direction: column;
border: 1px solid red;
}
.child {
background-color: wheat;
margin: 5px;
}
.second {
position: relative;
/* height to be set by JS */
}
.absolute {
position: absolute;
width: 100%;
top: 0;
left: 0;
}
<div class="container">
<div class="first child">
This content can grow and be as wide as it wants
</div>
<div class="second child">
<div class="absolute">
This content is longer than the above but still wraps in the right place.
</div>
</div>
</div>
Just set min-width and width of .second:
.container {
border: 1px solid red;
display: inline-block;
padding: 5px;
}
.child {
background-color: wheat;
}
.second {
margin-top: 10px;
min-width: 100%;
width: 0;
}
<div class="container">
<div class="first child">
This content can grow and be as wide as it wants
</div>
<div class="second child">
This content will also be any size it wants, but I * want it to wrap at the asterisk in this sentence, which is where the first child above would naturally end. This will be its own flexbox container holding several buttons that should wrap onto new rows.
</div>
</div>

Using CSS, how to add a pseudo element before every odd child element that is "outside" of that child element?

I want to create a grid with two columns whose width will be equal. My base HTML code looks like this:
<div class="linkgrid">
<div class="gridentry">
Loooooooooooooong
</div>
<div class="gridentry">
Short
</div>
<div class="gridentry">
Meeeedium
</div>
</div>
In this example, the first and the second gridentry should lie in the the first row. The thrid gridentry should lie in the second row. All gridentrys should have the same width.
~~~
I came up with a solution that uses a CSS table. However, to make sure the row "breaks" after every second cell, it currently requires non-semantic elements to force these "row breaks":
.linkgrid {
display: table;
border-spacing: 2px;
table-layout: fixed;
width: 50%;
}
.gridentry {
display: table-cell;
background-color: red;
padding: 5px;
text-align: center;
}
.gridentry a {
color: white;
}
.THIS-SHOULD-BE-A-PSEUDO-ELEMENT-BEFORE-EVERY-ODD-CHILD {
/* I imagine a selector that looks somewhat like this:
.linkgrid .gridentry:nth-child(odd):outsidebefore {
*/
display: table-row;
}
<div class="linkgrid">
<span class="THIS-SHOULD-BE-A-PSEUDO-ELEMENT-BEFORE-EVERY-ODD-CHILD"></span>
<div class="gridentry">
Loooooooooooooong
</div>
<div class="gridentry">
Short
</div>
<span class="THIS-SHOULD-BE-A-PSEUDO-ELEMENT-BEFORE-EVERY-ODD-CHILD"></span>
<div class="gridentry">
Meeeedium
</div>
</div>
Is there a way to remove my <span>s from my HTML (because they do not have any semantics) and use a clever CSS selector that adds them as pseudo elements at the right positions instead?
I do know that :before will "create" a pseudo-element within the selected element. Is there a non-JavaScript, CSS-only way to add a pseudo-element outside of the selected element like required in this example?
Another edit: For all those familiar with the Chrome developer tools, I want my result to look somewhat like this in the DOM tree:
<div class="linkgrid">
::outsidebefore
<div class="gridentry">
Loooooooooooooong
</div>
<div class="gridentry">
Short
</div>
::outsidebefore
<div class="gridentry">
Meeeedium
</div>
</div>
...where the ::outsidebefore pseudo-elements should have the CSS property display: table-row;.
Update 2016-01-04: While this specific question remains unanswered, my original problem was solved another way: https://stackoverflow.com/a/34588007/1560865
So please only post replies to this question that answer precisely the given question.
Display Level 3 introduces display: contents:
The element itself does not generate any boxes, but its children and
pseudo-elements still generate boxes as normal. For the purposes of
box generation and layout, the element must be treated as if it had
been replaced with its children and pseudo-elements in the document
tree.
Then, you can:
Wrap each cell in a container element
Set display: contents to those containers
Add ::before or ::after pseudo-elements to those containers
The result will look like as if the pseudo-elements were added to the cell, but outside it.
.wrapper {
display: contents;
}
.wrapper:nth-child(odd)::before {
content: '';
display: table-row;
}
.linkgrid {
display: table;
border-spacing: 2px;
table-layout: fixed;
width: 50%;
}
.wrapper {
display: contents;
}
.wrapper:nth-child(odd)::before {
content: '';
display: table-row;
}
.gridentry {
display: table-cell;
background-color: red;
padding: 5px;
text-align: center;
}
.gridentry a {
color: white;
}
<div class="linkgrid">
<div class="wrapper">
<div class="gridentry">
Loooooooooooooong
</div>
</div>
<div class="wrapper">
<div class="gridentry">
Short
</div>
</div>
<div class="wrapper">
<div class="gridentry">
Meeeedium
</div>
</div>
</div>
Note display: contents is not widely supported yet, but works on Firefox.
The most straightforward way is using an actual table structure. That is, one table divided into rows, in which the entries sit.
Also, you had width:50% on the table, but I believe from the question text that you meant every table cell to be 50% wide, rather than the table taking up 50% of the window width; so I corrected that.
.linkgrid {
display: table;
border-spacing: 2px;
}
.gridrow { /* new */
display: table-row;
}
.gridentry {
display: table-cell;
background-color: red;
padding: 5px;
text-align: center;
width: 50%; /* moved */
}
.gridentry a {
color: white;
}
<div class="linkgrid">
<div class="gridrow">
<div class="gridentry">
Loooooooooooooong
</div>
<div class="gridentry">
Short
</div>
</div>
<div class="gridrow">
<div class="gridentry">
Meeeedium
</div>
</div>
</div>

how to add 2 overlapping elements in a div?

<div id="parent" style="height:250px;width:250px;display:inline">
<div id="child" style="height:100%;width:100%;z-index:10001"></div>
<select style="height:100%;width:100%;z-index:10000"><option/></select>
</div>
My requirement is to include the select and child div elements inside the parent div in such a way that the child div is on top of the select element and completely covers it. Later I want to hide the child div based on an event and make the select element visible.
Both child div and select elements should occupy the entire size of parent div each on their own.
how can I achieve this?
http://jsfiddle.net/dyBjZ/2
#parent {
position: relative;
overflow: auto;
}
.child {
position: absolute;
height:100%;
width:100%;
}
<div id="parent">
<div class="child">
<select>
<option>One</option>
<option>Two</option>
</select>
</div>
<div class="child" id="child">Click me</div>
</div>
Taking input from the comments above, I was able to solve my problem. Here is what I did. Posting it here in case someone else lands up on this page searching.
<div id="parent" style="height:250px;width:250px">
<div id="child" style="display:block;height:100%;width:100%"></div>
<div id="selectParent" style="display:none;height:100%;width:100%">
<select><option/></select>
<div>
</div>
Based on the javascript event, I toggle display from block to none for child div. And toggle display from none to block in selectParent.
First issue is to give the #parent div a size, thus remove display: inline from its style.
Next, you could toggle for both elements from display: none to display: block, and v.v. But to reduce this by half, you could use absolute positioning which takes the element out of the default markup layout, as shown in this example.
HTML:
<div id="parent">
<div id="child"></div>
<select></select>
</div>
CSS:
#parent {
height: 250px;
width: 250px;
position: relative;
}
#child {
position: absolute;
background: #aaa;
height: 100%;
width: 100%;
}
select {
height: 100%;
width: 100%;
}
#child.hidden {
display: none;
}

Resources