Angular ngIf causes height CSS transition when toggling between two child components - javascript

I have a "button" component in Angular, with has a loading input. If the value is false it displays the text of the button, as displayed via content projection (<ng-content>). If true, it hides the content and displays a "spinner" component instead.
This done in the template using an *ngIf:
<button class="btn"
[ngClass]="{'loading': loading}">
<ng-content *ngIf="!loading"></ng-content>
<app-spinner *ngIf="loading"></app-spinner>
</button>
This works fine for toggling between the two views; if the Input on the button changes, the template renders it correctly.
However, when the input changes and the spinner is displayed, it causes a strange animation on the height of the button.
This happens when the button CSS has transition: all 0.25s ease-out;. If I comment that out, it's fine. But I want to keep the transition property if possible.
I've created a Stackblitz to demonstrate it:
https://stackblitz.com/edit/angular-ngif-in-button-strange-animation
I am wondering if it's because for split second, both components are in displayed while Angular's change detection is working, but I'm not sure.

I have tested your stackblitz and removing the padding from the .btn class will stop raising the button size.
This is happening because in the first frame, this padding from the .btn is being applied, making the button raise it's height. After that, the second style is applied from the .loading class, which resets the padding to padding: 0 12px and then the height goes to the normal size.

Related

Possible to use CSS transitions with textarea rows value?

In all the years I've been developing websites this situation has never cropped up before and I'm not sure that what I'm attempting to do is even possible.
I have a React component with a textarea. It's initial state is rendered with a height of 1 row like this :
state = {
rows: 1
}
...
<textarea
...
rows={this.state.rows ? this.state.rows : 1}
onFocus={this.onFocus}
...
/>
The onFocus function changes the rows state to 5, thereby expanding the textarea.
This works perfectly, but I'm now trying to add CSS transitions to the textarea so it expands nicely instead of just instantly expanding.
Everything I've tried doesn't work, for example :
textarea#content {
transition: all 2s ease-in-out;
}
...so my question is - is it not possible to use CSS transitions in this way? I did some googling and couldn't find any answers which leads me to believe that it isn't, but I just want to make sure before I set about achieving this another way.
Can't say how React might be involved here, but for a transition to work, the CSS property being transitioned must have a default value set for it. You are indirectly affecting the height property by changing the rows, but you are not actually specifying that you want the height to change, so you can't transition the height if you are only indirectly changing it. Also, there is no CSS rows property, so no luck on transitioning that either.
The solution is to not set the height indirectly with rows in the first place. Set the height directly and set a default value for height in the CSS.
And, you really don't even need JavaScript to do this:
textarea {
height:1em; /* Initial value required for transitions to work */
transition:height 1s ease-in-out; /* configure the transition*/
}
/* Style to be applied automatically when the textarea recievs the focus */
textarea:focus {
height:5em; /* A change in this property will trigger the transition */
}
<textarea></textarea>

Angular ui-select-match placeholder automatically setting width

I have <ui-select-match placeholder="Select areas...">{{$somestuff}}</ui-select-match>
The input box with the placeholder is getting its width set to 10px; automatically no matter what I do (as seen in the picture below). I have no idea why this is happening, and if I touch anything on the page or even adjust the size of the browser window it goes back to displaying the entire placeholder.
Does anyone know why this is happening? In the console I can see that it is says: element.style: width: 10px; but there is no reference to any css file where that is coming from, and I haven't touched any css files anyway.
The 10px width you are taking about is added by angular ui-select library. One solution you can do is override the width of the textbox by using css !important property.
.ui-select-container{
width:50px!important; //put whatever pixel value you need.it wont change
}
ui-select-container class is added by the library after the ui-select is rendered.

Intermediate state or something similar in vue

I am trying to get some text to scroll either horizontally , vertically or stay fixed depending on the space the current text needs. If it fits within the container it should stay fixed. If it does not, it should move. I don't know the text in advance and I have dynamic container size.
I am trying to check whether text overflows or not and it works fine out of mounted state for the component. I do this by comparing a combination of scrollheight to clientheight and textcontainer size vs the content container size.
<div id="content-container" :class="behaviourBasedClasses(data)">
<p id="text-container" :style="behaviourBasedTextStyle(data)">{{ text }}</p>
</div>
Updating also works as long as the text fits within the container. The problem is switching between animated and non-animated state. The data attribute in the code contains font-size and other attributes to logically decide the classes to use and the textstyles.
What I would need to solve the problem is the ability to get the text back into non-animated state. Then I could just use the routine I use in mounted state each time the text, font-size or container size changes.
states: no-scroll (non-animated):
<div id="content-container" class="no-scroll">
<p id="text-container" style="font-size:100px;">{{ text }}</p>
</div>
horizontal-scroll (animated):
<div id="content-container" class="scroll-horizontal">
<p id="text-container">{{ text }} style="font-size:120px; padding-left: 663.065px; position: relative; margin: auto 0px; line-height: 662.985px; animation-name: scroll-horizontal2; animation-duration: 79.4095s; animation-timing-function: linear; animation-iteration-count: infinite;"</p>
</div>
If the text is horizontally scrolled the scrollWidth gets really wide and it stays that way whatever change I make to the affecting data. Thus I am unable to get out of scrolling mode.
If I go into devtools and manually edit the markup back to no-scroll state the code works again. But I don't know how to get there programatically.

Bootstrap Collapse over an element

I'm using Bootstrap 3 to make a responsive website. However, I'm making a "portfolio".
You can see the website here as well as my "error".
http://basic-models.com/b/
Scroll down to "Our models" and click on "Informations". When you click on that button, it will collapse a new element below the profile picture of a model.
But that collapsible element is pushing the picture below the element to right for one column.
I guess I don't have to place code here since you can just right click > source code it.
Also, this is my first question on Stack Overflow, so I'm sorry if it is not formatted properly. Thank you for all the help.
You can change the CSS position attribute of the collapsing div to absolute. That way, the element will float over the below item - but you`ll have to apply styles a bit.
Try it like that:
.model-outer div.collapse {
position: absolute;
z-index: 1000;
background-color: white;
width:100%;
left:0px;
margin-top:10px;
}
You see, positioning and styles are not that good, but I assume you can start from there.
Since you are already using Bootstrap, I would suggest you to use default bootstrap dropdown . The problem with current code is that the div which shows the information is not absolutely positioned. So, whenever that div is displayed, it takes up the extra space and breaks the layout of the grid. Bootstrap dropdown uses absolute positioned div and hence it doesn't break the layout. Try using it and it will definitely solve this issue.

hide element without setting the display to none in jquery

I want to fold a section of the form without setting its display to none. If i set the display to none, the validation is bypassed that is why I don't want to set the display to none. I know I can set the visibility to hidden and visible but this solution is not feasible for rendering the view as the space for the folded section stays there. This results in a very odd look of the view with an empty white space with no content on it.
So my question is to hide a section of the html form (without intacting a placeholder for it) without setting its display to none, so that I could still perform the validation.
Some HTML code:
<td style="margin: 5px; border-bottom: 1px solid; display:none; overflow: hidden;" colspan="3">
<div>...</div>
</td>
The display is initially set to none but once it is unfolded for the first time, I am setting the height to 100% and removing the display style.
You can move it off the screen:
$(elem).css("position", "absolute").css("left", -9999);
Or set it's height to 0:
$(elem).css("height", 0);
The simplest way to fake display:none is by setting the position to absolute (so the element is taken out of flow, no longer influencing the rendering of outside elements) and the visibility to hidden (so it is no longer painted).
$(elem).css('visibility', 'hidden').css('position','absolute');
Set the opacity of the element to 0.
$(elem).css("opacity", 0);
$("#ele").css({"height" : 0, "width" : 0, "opacity" : 0});
Hiding an element with jquery...
$('element').addClass('hidden');
and in your CSS just use what ever you find appropriate to make that element "hidden"
.hidden{
/* whatever you find appropriate */
}

Categories