Css divs get placed in front of another when aboslute - html

I have a *ngfor that makes divs, but when i make the divs aboslute, the divs get place all at the same place instead of a list.
I need to make the divs aboslute to change the content inside of them with relative css.
html:
<ion-grid >
<div *ngFor="let card of restPointsCards;let i=index" id="card">
<ion-row>
<ion-col >
<ion-img *ngIf="userPercentageCards[i]>= 100" src="../../../assets/icons/PointsCard_100.png" ></ion-img>
<ion-img *ngIf="userPercentageCards[i]>= 85 && userPercentageCards[i] <100" src="../../../assets/icons/PointsCard_85.png"></ion-img>
<ion-img *ngIf="userPercentageCards[i]>= 70 && userPercentageCards[i]< 85" src="../../../assets/icons/PointsCard_70.png" ></ion-img>
<ion-img *ngIf="userPercentageCards[i]>= 50 && userPercentageCards[i]< 70" src="../../../assets/icons/PointsCard_50.png" ></ion-img>
<ion-img *ngIf="userPercentageCards[i]>= 30 && userPercentageCards[i]< 50" src="../../../assets/icons/PointsCard_30.png" ></ion-img>
<ion-img *ngIf="userPercentageCards[i]>= 15 && userPercentageCards[i]< 30" src="../../../assets/icons/PointsCard_15.png" ></ion-img>
<ion-img *ngIf="userPercentageCards[i]< 15 && userPercentageCards[i]> 0" src="../../../assets/icons/PointsCard.png"></ion-img>
</ion-col>
<ion-col >
<ion-text> {{card.cardPoints}} = {{card.cardValue}} € </ion-text>
<!-- <ion-text>{{userPercentageCards[i]}} %</ion-text>-->
<ion-button id="useButton" *ngIf="userPercentageCards[i] >=100" style="bottom: 0"> Usar Cartão!</ion-button>
</ion-col>
</ion-row>
</div>
css:
#card{
position: absolute;
border: #5e8d93 2px solid ;
margin-top: 5px;
height: 140px;
width: 70%
}
I want to change the position of the images and buttons inside the div thats why i want to make the div aboslute, so i can change for exemple the button like this:
css:
#useButton{
position: relative;
bottom: 5px;
}

that is exactly what position: absolute does, it places an element at an absolute position that is relative to the body or another parent with position: relative. In this case using position absolute is bound to place them in the same area of the div.

I have No Idea why you would be using Position:absolute elements but Let's assume there are no other conflicts. wrap the #card container with a div/span and give it a class="relative" You can wrap any absolute elements, this will allow the absolute element to exist as a static element and continue with the flow BUT they are unpredictable.
add this css class to the document
.relative{
position: relative;
display: inline-block;
width:100%;
height:100%;
}
you can name the class whatever you want, But caution: absolute behaviour depends on whatever elements and styles, assuming there are not other styles involved this should list the elements underneath each other with the exception of overflow elements.
For whatever Reason I would not recommend absolute elements as they always disrupt the flow of the HTML so unless you ABSOLUTELY have to. consider using the above css to allow the elements to not overlap.
If you want a more effective solution consider using Pastebin or Codepen than we can help get the desired effect intended without rellying on absolute elements.

Related

Creating a side bar using HTML + CSS in Ionic Framework

I am trying to create a page with the Ionic Framework and Angular which has a sidebar, and some text content against that sidebar. Right now, the sidebar works well, but when I try to add some text content, the text ends up underneath the sidebar. I am assuming this is because the sidebar is positioned as absolute, and thus is out of the document flow.
Here is my current code:
<div id="sidebar_button_container">
<ion-button href="start-game" color="dark" expand="block">{{ newgame_text }}</ion-button>
<ion-button href="view-previous-games" color="dark" expand="block">{{ viewgames_text }}</ion-button>
</div>
<div id="text_content">
Test. Example Text, This is so that I can read it wherever it is.
</div>
#sidebar_button_container {
text-align: center;
position: absolute;
left: 0;
top: 55px;
bottom: 0;
padding-right: 5px;
padding-left: 5px;
background-color: #dddddd;
}
#media screen and (min-width:400px) {
#sidebar_button_container {
right: 80%;
}
}
#media screen and (max-width:400px) and (orientation:portrait) {
#sidebar_button_container {
right: 50%;
}
}
#media screen and (max-width:600px) and (orientation:landscape) {
#sidebar_button_container {
right: 60%;
}
}
(Btw, the top position of the sidebar is because there is an ion-toolbar at the top of the page, and the media checks are only tested on my phone and laptop, and are included here only for a more complete picture of my code.)
In this picture, you can see that the text in the text_content div is hidden behind the sidebar. I would like to know how I could position the text against the sidebar instead of behind it, while keeping the sidebar intact, and preferably without hardcoding a lot of values in when I want to add paragraphs or line breaks.
You can try a number of things.
The first one that comes to mind for me at-least is to add a CSS padding-left property to "text_content". Short term I don't think this is the best solution, given you will likely have various screen dimensions, and on smaller screens the padding might push the text too much to the right.
The Second idea that comes to mind would be to create a parent/container div. (as shown below) and try adding some flex-box to the "container" CSS class using the following resource (https://css-tricks.com/snippets/css/a-guide-to-flexbox/).
<div id='container'>
<div id="sidebar_button_container">
<ion-button href="start-game" color="dark" expand="block">{{ newgame_text
}}</ion-button>
<ion-button href="view-previous-games" color="dark" expand="block">{{
viewgames_text }}</ion-button>
</div>
<div id="text_content">
Test. Example Text, This is so that I can read it wherever it is.
</div>
</div>
The last potential idea/solution I have would be to make the "text_content' relative to the parent. You can find an example of how to do that here (Position absolute but relative to parent).
I hope this helps you find the solution, this is one of my first Stack Overflow contributions, so apologies for not being able to provide an immediate answer. (If you have a public repository you are willing to share, I could clone down your project, and do some more tinkering myself). Cheers.
You should have a look at ionic grid
You can write something like
<ion-grid>
<ion-row>
<ion-col size="2">
<ion-button
href="start-game"
color="dark"
expand="block"
>{{ newgame_text }}</ion-button>
<ion-button
href="view-previous-games"
color="dark"
expand="block"
>{{ viewgames_text }}</ion-button>
</ion-col>
<ion-col>
Test. Example Text, This is so that I can read it wherever it is.
</ion-col>
</ion-row>
</ion-grid>

ion-grid with alternate columns

I'm not very familiar with Angular. I would like to have a grid like this:
i.e. have one image per row alternating with two images.I tried with this code but I get a slightly different grid (I also get the same image twice because I don't know how to increase the index inside the loop):
.html:
<ion-content>
<ion-grid class="design">
<ion-row size="12" *ngFor="let t of types ; let i=index">
<ion-col *ngIf="i%3==0" size="12">
<img oncontextmenu="return false;" src={{t?.img}} class="center" />
</ion-col>
<ion-col *ngIf="i%3!=0" size="6">
<img oncontextmenu="return false;" src={{t?.img}} class="center" />
</ion-col>
<ion-col *ngIf="i%3!=0" size="6">
<img oncontextmenu="return false;" src={{types[i+1]?.img}} class="center"/>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
.scss:
.design {
position: center;
width: 90%;
height: 90%;
margin-left: auto;
margin-right: auto;
}
.center {
display: block;
width: 100%;
}
How could I modify it ?
You need to wrap rows in ion-row element and everything in the ion-grid, then you can use ion-col for each column. Here is the simple example of full-width element and 2-column row: https://stackblitz.com/edit/ionic-yxpfht?file=pages%2Fhome%2Fhome.ts
You may also refer to the official docs since there is a nice example as well of how to use grid. Additionally, you may want to manipulate spacing/gutter, which is explained in the docs.
And if you have your images in array, like this `['img1', 'img2', 'img3'] you may want to check if you have 3 to display them 2 + 1 (2 in the first row and 1 in the second), so then you can just use something like on the stackblitz example.

ion refresher and fixed element

index behind other div
I drawed a red ligne where the index were
so i have a div which is fixed, but with my ion-refresher,
the fixed div seem to go in absolute when i pull to refresh, i don't know how to fix this.
here my code
.alphabetItem {
color: #ffffff;
font-size: 10px;
position: fixed;
z-index: 99999999;
right: -4%;
top : 200px;
}
<ion-refresher (ionRefresh)="doRefresh($event)">
<ion-refresher-content pullingIcon="arrow-dropdown" pullingText="Tirer pour rafraîchir" refreshingSpinner="circles" refreshingText="Relâcher pour rafraîchir ...">
</ion-refresher-content>
</ion-refresher>
<ion-col col-1 class="alphabetItem" scrollY="true" style="width:100%; height:100%">
<div class="divLetter" *ngFor="let letter of alphabets" (click)="alphaScrollGoToList(letter)">
{{letter}}
</div>
</ion-col>
Try to use ion-toolbar component from Ionic Framework (https://ionicframework.com/docs/api/components/toolbar/Toolbar/).
<ion-header>
<ion-toolbar>
<!-- your fixed col -->
</ion-toolbar>
</ion-header>
<ion-content>
...
<!-- your content + refresher -->
...
</ion-content>
The ion-refresher is a really special component. No matter where you place it, it will be put at the top of the nearest ion-content. When you refresh, it will move down your scroll-content, where your fixed container is placed in. <ion-toolbar> should fix this problem.

How to attach a Vuetify v-menu to its parent element in a scrollable list?

In my project, I have a scrollable list of items, and each item has a menu that is opened when its activator button is hovered.
By default, v-menu elements are attached to the v-app element, which serves as a mounting point for many Vuetify elements. When I use this default behavior, the generated HTML contains many detached div elements for the popup menu, one per item in the list, in the generated v-app div:
<div class="menu__content" style="min-width: 0px; top: 12px; left: 0px; transform-origin: left top 0px; z-index: 0; display: none;"></div>
This is impacting the reading of the rendered DOM, and the result is a bit messy especially when debugging.
Also, once the menu is opened, and the list is scrolled, the menu remains at a fixed position and therefore gets visually detached from its activator button.
How could I attach the menu to each item of the list in order to have a more readable rendered DOM (see below)?
<my-list>
<my-item>
<div class="menu__content" style="min-width: 0px; top: 12px; left: 0px; transform-origin: left top 0px; z-index: 0; display: none;"></div>
</my-item>
</my-list>
And how can I have the v-menu stick to its activator button when the list is scrolled?
Check out the documentation under the following link and search for "attach":
https://vuetifyjs.com/en/components/menus
"Attach": Specifies which DOM element that this component should detach to. Use either a CSS selector string or an object reference to the element.
So when you have a menu like e.g. this:
<v-menu>
<v-btn slot="activator">
Click
</v-btn>
<v-card>
Content
</v-card>
</v-menu>
You can attach it to an element, let's say the button itself, like so:
<v-menu attach="#fooAnchor">
<v-btn slot="activator" id="fooAnchor">
Click
</v-btn>
<v-card>
Content
</v-card>
</v-menu>
And of course you can place id="fooAnchor" wherever you want.
This is the latest solution you can try this one below
<v-menu
offset-x
bottom
right
attach="zoom-feature"
>
<template v-slot:activator="{ on, attrs }">
<v-btn
id="zoom-feature"
v-bind="attrs"
v-on="on"
>
Click Me
</v-btn>
</template>
<v-card>
I am Card
</v-card>
</v-menu>

Ionic 2 Range With Labels

I am looking to add some labels to an Ionic 2 range element (the documentation for which can be found at http://ionicframework.com/docs/v2/api/components/range/Range/)
You can add a label at the beginning and end using the following markup
<ion-range min="-200" max="200" [(ngModel)]="saturation" color="secondary">
<!-- Setting the labels here -->
<ion-label range-left>-200</ion-label>
<ion-label range-right>200</ion-label>
</ion-range>
I would however like to add some labels throughout the range, on either side if possible in an attempt to make it look more like a progress bar. So you might have labels like 25%, 50% etc ..
What would be a good way to approach this, without interfering too much with the Ionic HTML?
My approach so far is just to create an ion-row above the range, then use css to place it.
HTML
<!-- TIMELINE -->
<div class='timeline'>
<ion-grid class="timeline-grid">
<ion-row class="timeline-labels">
<ion-col width-20>Label One</ion-col>
<ion-col width-20>Label Two</ion-col>
<ion-col width-20>Label Three</ion-col>
<ion-col width-20>Label Four</ion-col>
<ion-col width-20>Label Five</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-item>
<ion-range color='secondary' [(ngModel)]="progress">
</ion-range>
</ion-item>
</ion-col>
</ion-row>
</ion-grid>
</div>
CSS
ion-row.timeline-labels {
padding-left: 20px;
z-index: 1;
position: absolute;
top: 10px;
}
Which does in a way work, however I am thinking there is maybe a better/cleaner way to go about it.
Any advice would be great.
Thanks!
Wouldn't setting the pin="true" (in the range slider tag) basically do what you want?
It would show the current value of the slider like a progress bar would.
If you are looking to achieve more of a specified label at the bottom at specific points I think the best way would be to add a div with spans directly below the range slider and then toy with the CSS till its close enough to what you want.
main css issues will be removing padding or margin space around the Range element, and then getting the font size and spacing of the 'progress' in the right spots.
eg.
<ion-range min="0" max="100" pin="true">
<!-- Setting the labels here -->
<ion-label range-left>0</ion-label>
<ion-label range-right>100</ion-label>
</ion-range>
<div>
<span>20%<span>
<span>40%<span>
<span>80%<span>
<span>100%<span>
</div>
This might be too late but for others looking in the future I put my labels inside of spans within a label below and used css to style the padding and width.
Here is my HTML:
<div class="slide-rating">
<ion-range min="1" max="4" step="1" snaps="true" ticks="false" ></ion-
range>
<ion-label class="rating-labels">
<span> Beginner </span>
<span> Casual </span>
<span> Advanced </span>
<span> Expert </span>
</ion-label>
</div>
And my CSS:
span{
color: #354D37;
font-family: Gotham-Book;
font-size: small;
padding-left: 12px;
}
.slide-rating{
align-items: center;
width: 80%;
position: absolute;
top: 70%;
left: 50%;
transform: translate(-50%, -50%);
}
.rating-labels{
margin-left: -5%;
margin-right: -5%;
text-align: center;
}