How can we add before after css code dynamically with vue? - javascript

I am trying to solve a problem which I actually never faced. I am trying apply dynamic color from my data inside v-for loop. Now normal css properties are easily appliable. I need to apply css for after. I tried
<div class="_tmln_shdl_crd_itm" v-for="(t, i) in timeLine" v-if="timeLine.length">
<div class="_tmln_shdl_itm_lft">
<p :style="`color:${t.color}`">{{t.time}}</p> // THIS WORKS
</div>
<style>
._tmln_shdl_itm_r8_one h4:after{ // TRIED TO WRITE CSS WITH FOR LOOP BUT FAILED :D
color: t.color
}
</style>
<div>
So how can I make it work for ._tmln_shdl_itm_r8_one h4:after ?
Any solution?
Thank you.

The style you create in the loop creates CSS for the same selector every time. The browser only has one applicable CSS styling for this selector.
With the same selector, the newest CSS wins and is applied. This is CSS Specificity ("When multiple declarations have equal specificity, the last declaration found in the CSS is applied to the element.").
You can create classes dynamically:
<div class="_tmln_shdl_crd_itm" v-for="(t, i) in timeLine" v-if="timeLine.length">
<div :class="`_tmln_shdl_itm_lft _tmln_shdl_itm_lft-${i}`">
<h4>{{ t.time }}</h4>
</div>
<style>
._tmln_shdl_itm_lft-{{ i }} h4:after{
color: {{ t.color }};
}
</style>
<div>
Something like that should work. Making the class dynamic with ._tmln_shdl_itm_lft-{{ i }} makes the magic work.
This also adds a lot of CSS fluff to the page which is probably not what you want in a live environment.
Remarks:
You also should output t.color like this (probably just a mistake in your example):
color: {{ t.color }};
There is also no h4 tag in your example code that the CSS could apply for, but that's probably somewhere else in your page.. hopefully?

Related

Changing the color of embeded text

I have been trying to get this text color to be white rather than black so it can be more readable on our site. Unfortunately I have been unsuccessful in changing it. Im not sure what I am missing lol im sure its right in front of me though. I did go through a website to embed this as well.
<div id="medium-widget">
</div>
<script src="https://medium-widget.pixelpoint.io/widget.js">
</script>
<script>MediumWidget.Init({renderTo: '#medium-widget', params: {"resource":"https://medium.com/paradigm-fund/c%C3%B8smos-network-proposal-to-add-the-gravity-dex-onto-cosmos-hub-is-live-tendermint-invests-in-c68d8600e35b","postsPerLine":3,"limit":6,"picture":"big","fields":["description","publishAt"],"ratio":"original"}})
</script>
I believe you could just inspect the element and overwrite the CSS like this:
Using color red for example:
.medium-widget-article__description{
color: red !important;
}
<div id="medium-widget">
</div>
<script src="https://medium-widget.pixelpoint.io/widget.js">
</script>
<script>MediumWidget.Init({renderTo: '#medium-widget', params: {"resource":"https://medium.com/paradigm-fund/c%C3%B8smos-network-proposal-to-add-the-gravity-dex-onto-cosmos-hub-is-live-tendermint-invests-in-c68d8600e35b","postsPerLine":3,"limit":6,"picture":"big","fields":["description","publishAt"],"ratio":"original"}})
</script>
Quoted from medium-widget.pixelpoint.io
Customize styles
This widget does not use iframes, which allows you to
override all of the existing styles used by it and make it look
however you like. For example, you could customize the style of the
article title by simply defining css properties for
medium-widget-article__title class.

CSS and Dynamic Content

UPDATE: Messed up with my CSS, as nothing to do with dynamic content.!
The answer is very informative though!
I'm creating tags and inserting content with handlebars:
Handlebars code:
{{#each docs}}
<article class="first">
<p class="date">
{{#date}} {{date}}
</p>
<h4 class="header">{{#venue.title}} {{venue.title}}
- {{#venue.city}} {{venue.city}}</h4>
<p class="details">
{{#description}} {{description}}
</p>
</article>
{{/each}}
If I just list articles, the CSS works - but when I let handlebars dynamically create them, it won't apply.
CSS code:
div.gig-items{
article: nth-of-type(n +2);
height: 0;
padding: 0;
}
Is there a way to first create the content and then apply CSS or some more elegant solution?
The CSS is applied automatically at each repaint. So inserting your code in the source html or dynamically with js doesn't matter, the css will be applied correctly.
The problem come for sure from your code which has several errors...
First the CSS
You want to style every div elements with class gig-items, but
there is no div and no class gig-items in your template...
You define a property article with value nth-of-type(n+2), but this is not a property, this is a selector
you should use it like :
article:nth-of-type(n+2) {
color: blue;
}
Then in your handlebar template :
I assume you want to insert values by their names, but you use the
prefix # which is reserved for handlebar's loop values like
#index or #keys
Another error is that you write double handlebar
block to display the value. One is enough.
The correct way to insert value is :
<p class="date">{{date}}</p>

Flex, AngularJS + Masonry, akoenig/angular-deckgrid and more [duplicate]

This question already has answers here:
How to Create Grid/Tile View? [duplicate]
(8 answers)
Closed 6 years ago.
I've been sending this emails:
I'm about to release an application for web application security which requires the use of a grid like Masonry. I've tried all, and every single angular module, directives, and different approaches, including CSS based techniques, pure Vanilla JS, and your solution is, one of the best options available online. I found, however a main issue, that affects not only your approach, but every single Angular module or addon.
Issue #1:
Your solution, as any other solution, is based on an array of information that is already handled by angular. In your example case, it would be source="photos". Now, the problem comes when there's 2 different groups of elements. Let's assume, that I have a group of elements that where previously defined in the DOM. In other words:
<div angular-grid>
<p class="angular-grid-elem">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
<div class="angular-grid-elem" style="height:500px">Same happens with this content.</div>
<!-- and here comes more content, which is loaded from an array of information -->
<div class="angular-grid-elem" ng-repeat="data in data_array">
<p>{{data.header}}</p>
<p>{{data.details}}</p>
</div>
</div>
Now, as you can see in the example, the content inside the main div, , should be all, affected by the masonry layout. Of course, this is pseudo code and I'm aware that the sintaxis of your approach is different. However what I'm trying to represent here, is that your module, would be way better, if you would be able to apply the masonry like grid, including elements which are already present in the DOM/HTML in first place, with elements that are coming from an array.
Issue #2:
There's a second issue I found in multiple angular modules and approaches. What happens if I have 2, 3 or let's say even 16 divs which all of them, present the same masonry like behaviour? I have to admit, I didn't try it with your module, as I couldn't solve the initial problem, that requires the proper handling of the combination of elements that are (1) pre-defined in the HTML, and (2) coming from and ng-repeat function.
A possible approach:
In order to solve the second problem and the first one, at the same time, I have thought that the best approach might be to make use of element classes and elements ids to handle the situation? Why? Because it can easily applied into elements that are already there in the DOM in first place, as well, to elements that are joining or leaving dynamically by the use of a ng-repeat or any other of the angular functions.
Here's an example of what I'm saying:
<div class="angular-grid-dad-one" ng-grid="{'dad': 'angular-grid-dad-one', 'childs': 'angular-grid-elem'}" >
<p class="angular-grid-elem">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
<div class="angular-grid-elem" style="height:500px">Same happens with this content.</div>
<!-- and here comes more content, which is loaded from an array of information -->
<div class="angular-grid-elem" ng-repeat="data in data_array">
<p>{{data.header}}</p>
<p>{{data.details}}</p>
</div>
</div>
In this case, the main div defines itself as id="angular-grid-dad-one",
And also tells the Angular module, that the element angular-grid-dad-one is a container div of a masonry like structure,
And that it's childs are marked as angular-grid-elem.
As we could see on this line.
ng-grid="{'dad': 'angular-grid-dad-one', 'childs': 'angular-grid-elem'}"
This way, it allow us to make use of the Angular module in multiple instances. For example.
<div class="seccion_01" ng-grid="{'dad': 'seccion_01', 'childs': 'seccion_01_child'}" ng-show="seccion == '1'">
<p class="seccion_01_child">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
<div class="seccion_01_child" style="height:500px">Same happens with this content.</div>
<!-- and here comes more content, which is loaded from an array of information -->
<div class="seccion_01_child" ng-repeat="data in data_array">
<p>{{data.header}}</p>
<p>{{data.details}}</p>
</div>
</div>
<div class="another_container" ng-grid="{'dad': 'another_container', 'childs': 'child_of_container'}" ng-show="seccion == '2'">
<p class="child_of_container">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
<div class="child_of_container" style="height:500px">Same happens with this content.</div>
<!-- and here comes more content, which is loaded from an array of information -->
<div class="child_of_container" ng-repeat="data in data_array">
<p>{{data.header}}</p>
<p>{{data.details}}</p>
</div>
</div>
<div class="redundant_example" ng-grid="{'dad': 'redundant_example', 'childs': 'childs_of_redundancy'}" ng-show="seccion == '3'">
<p class="childs_of_redundancy">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
<div class="childs_of_redundancy" style="height:500px">Same happens with this content.</div>
<!-- and here comes more content, which is loaded from an array of information -->
<div class="childs_of_redundancy" ng-repeat="data in data_array">
<p>{{data.header}}</p>
<p>{{data.details}}</p>
</div>
</div>
I have used a Json styled instruction in the ng-grid value in order to explain my point, but it doesn't really have to be Json. It even could be 2 different paramenters:
<div class="dad" ng-grid-dad="dad" ng-grid-childs="childs" ng-show="seccion == '3'">
<p class="childs">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
<div class="childs" style="height:500px">Same happens with this content.</div>
<!-- and here comes more content, which is loaded from an array of information -->
<div class="childs" ng-repeat="data in data_array">
<p>{{data.header}}</p>
<p>{{data.details}}</p>
</div>
</div>
As well, regarding the infinite scroll that you have created, you would be able to load more elements, triggering the infinite scroll, and loading only elements from one specific array, of course.
Please let me know if I can help further, I would like to integrate your module into my application.
And let's hope that by the next implementation of HTML and CSS we have this situation fully under control by the next generation of browsers, I'm aware of the work it takes to make this grids in Javascript.
Actually, I am gonna go out on a limb and say that flex-wrap: wrap will fix the issue.
.holder {
flex-wrap: wrap
-moz-columns: 2 auto;
box-sizing: border-box;
display: flex;
padding: 0 40px;
width: 100%;
}

Automatically resizing font-size in ng-repeat

I am currently trying to resize font-size to fit inside a fixed size div. I found this interesting piece of javascript code doing the job very well
$('#defect-text div').css('font-size', '1em');
while ($('#defect-text div').height() > $('#defect-text').height()) {
$('#defect-text div').css('font-size', (parseInt($('#defect-text div').css('font-size')) - 1) + "px");
}
For the following HTML code
<div ng-repeat="defect in surface.defects" class="new-page">
<div id="defect-text">
<div>
<div id="defect-title">{{ 'TYPE' | translate }}:</div>
{{ defect.type }}
<div id="defect-title">Emplacement du défaut:</div>
{{ defect.location }}
<div id="defect-title">Dimension du défaut:</div>
{{ defect.dimension }}
<div id="defect-title">Actions suggérées:</div>
{{ defect.future_operation }}
<div id="defect-title">Détail technique du défaut:</div>
{{ defect.description }}</div>
</div></div>
However, since the different div are inside an ng-repeat expression, my piece of javascript code will resize the font of every container with the desired size of the first one. Is there a way to change to code to select the current element of the ng-repeat and change only it's own css to fit the container?
thanks in advance
I think your problem is actually one of scope:
$('#defect-text div').css('font-size'...)
You're selecting ALL <div> descendants (no matter how deep) of the id="defect-text" element and modifying them at this time. Technically an ID MUST be unique (behavior is not well defined if you have multiple elements with the same ID), and I think your selector is grabbing ALL of the <div> contained within ANY #defect-text elements, which is probably a lot broader than you want, inside of this particular loop.
I would recommend modifying your ng-repeat block and replacing the ID using the angular expression language like
<div id="{{ defect.id }}">
then you can use $("#"+defect.id + " div") to get all <div> descendants of a unique defect.
I'd also consider using the child selector "> div" instead of all descendants.

CSS Multiple ID with Same Name Work Around?

First I realize ID's should be unique. But right now I can't do much about that. I have a javascript plug-in that is generating ID names and for one page it works great. The issue is in creating another page, it will start over using the same naming convention. For example:
Page 1
<ul id="1">
Page 2
<ul id="1">
So if I am trying to style ul#1 on Page 1 it will also style ul#1 on Page 2. So, any suggestions on how to separate our the two id's? This html is generated by the JS, otherwise I would just attach a class to it.
Thanks.
First, the unique ID suggestion is restricted to a page. It is perfectly fine to have multiple ID's on different pages. The best way to overcome this is to add a ID to the body.
Page1
<body id="Page1">
<ul id="1">
<li></li>
</ul>
</body>
Page2
<body id="Page2">
<ul id="1">
<li></li>
</ul>
</body>
CSS
#Page1 #1
{
//Some style for page 1, ID 1
}
#Page2 #1
{
//Some style for page 2, ID 1
}
Can you attach a class around it ? Have a div or span some other element surround your code that does the generation and assign a class to it.
I'd say you have to use different style sheets on each page if you need different styles for the same ids, but this will be a pain to maintain as you make styling changes.
Alternatively you could you assign a class to one of the page's UL tags and then create a style for that class.
First of all, the plugin is still not generating the correct ids because ids can't be numbers. To answer your question, try to figure out some parent element that might be different between the two pages probably in which case you can use CSS such as this:
#parent ul#1{
/* styles here */
}
#parent2 ul#1{
/* styles here */
}
page1:
<div id="parent">
<ul id="1">
............
page2:
<div id="parent2">
<ul id="1">
............
So you need to find out a some parent element of ul which is not common between the two pages. This is the only possibility that comes to my mind where you have no control over changing the ids or replacing them with classes since they are being generated by the plugin.
You need something to distinguish them if you want them styled separately. If you cannot modify those tag you could probably use some parent container like:
<div id="parent1">
<ul id="id1" />
</div>
<div id="parent2">
<ul id="id1" />
</div>
and then:
#parent1 ul {
...
}
#parent2 ul {
...
}
Also notice that an id cannot start with a number as in your case. You should probably consider switching/modifying this plugin.
One thing I commonly do is attach a class to the body for each page. <body class="home_section"> and then you could style based on that class .home_section ul#1 {}.
Also, IDs must begin with a letter.

Categories

Resources