Hi,
While using Metronic 4 with angular and asp.net core, I've built a specific component for horizontal-timeline. It was working great. I've upgraded my project with latest aspnetzero version and with metronic 5. In metronic 5, it is not available in the demo templates.
I also noticed that you removed it from aspnetzero dashboard.
Do you know if this component will be available soon for metronic 5 ?
Is it possible to get the horizontal-timeline work again (with metronic 4 assets) and how will you do it ?
Any advice would be welcome :)
5 Answer(s)
-
0
Hi @Ricavir,
We have spent a little time on migration the horizontal timeline from v4.x to v5.x and then decided to give up because it was going to hard.
This is the timeline used <a class="postlink" href="https://github.com/CodyHouse/horizontal-timeline">https://github.com/CodyHouse/horizontal-timeline</a> and it seems like it's abandoned. We also couldn't find any other good option for horizontal timeline.
-
0
Hi @ismcagdas,
I managed to make it work again. It was mainly css stuff to be reintegrated and adapted to Metronic 5.
My horizontal-timeline component was not the same as yours. I completely wrap it in an angular component. I've also added missing css file for horizontal-timeline in angular.cli
If you're interested, I can share it
Cheers
-
0
it would be great if you share it for the one's who may want to use it
-
0
Here it is :
timeline.component.ts : wraps javascript for horizontal timeline
import { Component, AfterViewInit, Injector, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core'; import { AppComponentBase } from '@shared/common/app-component-base'; import { TimelineItemDto } from '@shared/service-proxies/service-proxies'; import * as moment from 'moment'; @Component({ selector: 'timeline', styles: ['./timeline.component.css'], templateUrl: './timeline.component.html', encapsulation: ViewEncapsulation.None }) export class TimelineComponent extends AppComponentBase implements AfterViewInit { @Input() timelineItems: TimelineItemDto[]; @Input() selectedItemId: number = 0; selectedItemIdAfterInit: number = 0; @Output() timelineItemClicked = new EventEmitter<TimelineItemDto>(); constructor( injector: Injector ) { super(injector); } ngAfterViewInit(): void { var timelines = $('.cd-horizontal-timeline'); this.selectedItemIdAfterInit = this.selectedItemId; (timelines.length > 0 && this.timelineItems.length > 0) && initTimeline(timelines, this.timelineItems, this.selectedItemId); } timelineItemClick(item: TimelineItemDto) { this.timelineItemClicked.emit(item); } } function initTimeline(timelines, items, selectedItemId) { timelines.each(function () { var eventsMinDistance = $(this).data('spacing'); var timeline = $(this), timelineComponents = {}; //cache timeline components timelineComponents['timelineWrapper'] = timeline.find('.events-wrapper'); timelineComponents['eventsWrapper'] = timelineComponents['timelineWrapper'].children('.events'); timelineComponents['fillingLine'] = timelineComponents['eventsWrapper'].children('.filling-line'); timelineComponents['timelineEvents'] = timelineComponents['eventsWrapper'].find('a'); timelineComponents['timelineDates'] = parseDate(items); timelineComponents['eventsMinLapse'] = minLapse(timelineComponents['timelineDates']); timelineComponents['timelineNavigation'] = timeline.find('.cd-timeline-navigation'); timelineComponents['eventsContent'] = timeline.children('.events-content'); //assign a left postion to the single events along the timeline setDatePosition(timelineComponents, eventsMinDistance); //assign a width to the timeline var timelineTotWidth = setTimelineWidth(timelineComponents, eventsMinDistance, selectedItemId); //the timeline has been initialize - show it timeline.addClass('loaded'); //detect click on the next arrow timelineComponents['timelineNavigation'].on('click', '.next', function (event) { event.preventDefault(); updateSlide(timelineComponents, timelineTotWidth, 'next', eventsMinDistance); }); //detect click on the prev arrow timelineComponents['timelineNavigation'].on('click', '.prev', function (event) { event.preventDefault(); updateSlide(timelineComponents, timelineTotWidth, 'prev', eventsMinDistance); }); //detect click on the a single event - show new event content timelineComponents['eventsWrapper'].on('click', 'a', function (event) { event.preventDefault(); timelineComponents['timelineEvents'].removeClass('selected'); $(this).addClass('selected'); this.selectedItemIdAfterInit = $(this).get(0).id; updateOlderEvents($(this)); updateFilling($(this), timelineComponents['fillingLine'], timelineTotWidth); updateVisibleContent($(this), timelineComponents['eventsContent']); }); //on swipe, show next/prev event content timelineComponents['eventsContent'].on('swipeleft', function () { var mq = checkMQ(); (mq == 'mobile') && showNewContent(timelineComponents, timelineTotWidth, 'next'); }); timelineComponents['eventsContent'].on('swiperight', function () { var mq = checkMQ(); (mq == 'mobile') && showNewContent(timelineComponents, timelineTotWidth, 'prev'); }); //keyboard navigation $(document).keyup(function (event) { if (event.which == 37 && elementInViewport(timeline.get(0))) { showNewContent(timelineComponents, timelineTotWidth, 'prev'); } else if (event.which == 39 && elementInViewport(timeline.get(0))) { showNewContent(timelineComponents, timelineTotWidth, 'next'); } }); }); } function updateSlide(timelineComponents, timelineTotWidth, string, eventsMinDistance) { //retrieve translateX value of timelineComponents['eventsWrapper'] var translateValue = getTranslateValue(timelineComponents['eventsWrapper']), wrapperWidth = Number(timelineComponents['timelineWrapper'].css('width').replace('px', '')); //translate the timeline to the left('next')/right('prev') (string == 'next') ? translateTimeline(timelineComponents, translateValue - wrapperWidth + eventsMinDistance, wrapperWidth - timelineTotWidth) : translateTimeline(timelineComponents, translateValue + wrapperWidth - eventsMinDistance, undefined); } function showNewContent(timelineComponents, timelineTotWidth, string) { //go from one event to the next/previous one var visibleContent = timelineComponents['eventsContent'].find('.selected'), newContent = (string == 'next') ? visibleContent.next() : visibleContent.prev(); if (newContent.length > 0) { //if there's a next/prev event - show it var selectedDate = timelineComponents['eventsWrapper'].find('.selected'), newEvent = (string == 'next') ? selectedDate.parent('li').next('li').children('a') : selectedDate.parent('li').prev('li').children('a'); updateFilling(newEvent, timelineComponents['fillingLine'], timelineTotWidth); updateVisibleContent(newEvent, timelineComponents['eventsContent']); newEvent.addClass('selected'); selectedDate.removeClass('selected'); updateOlderEvents(newEvent); updateTimelinePosition(string, newEvent, timelineComponents); } } function updateTimelinePosition(string, event, timelineComponents) { //translate timeline to the left/right according to the position of the selected event var eventStyle = window.getComputedStyle(event.get(0), null), eventLeft = Number(eventStyle.getPropertyValue("left").replace('px', '')), timelineWidth = Number(timelineComponents['timelineWrapper'].css('width').replace('px', '')), timelineTotWidth = Number(timelineComponents['eventsWrapper'].css('width').replace('px', '')); var timelineTranslate = getTranslateValue(timelineComponents['eventsWrapper']); if ((string == 'next' && eventLeft > timelineWidth - timelineTranslate) || (string == 'prev' && eventLeft < - timelineTranslate)) { translateTimeline(timelineComponents, - eventLeft + timelineWidth / 2, timelineWidth - timelineTotWidth); } } function translateTimeline(timelineComponents, value, totWidth) { var eventsWrapper = timelineComponents['eventsWrapper'].get(0); value = (value > 0) ? 0 : value; //only negative translate value value = (!(typeof totWidth === 'undefined') && value < totWidth) ? totWidth : value; //do not translate more than timeline width setTransformValue(eventsWrapper, 'translateX', value + 'px'); //update navigation arrows visibility (value == 0) ? timelineComponents['timelineNavigation'].find('.prev').addClass('inactive') : timelineComponents['timelineNavigation'].find('.prev').removeClass('inactive'); (value == totWidth) ? timelineComponents['timelineNavigation'].find('.next').addClass('inactive') : timelineComponents['timelineNavigation'].find('.next').removeClass('inactive'); } function updateFilling(selectedEvent, filling, totWidth) { //change .filling-line length according to the selected event var eventStyle = window.getComputedStyle(selectedEvent.get(0), null), eventLeft = eventStyle.getPropertyValue("left"), eventWidth = eventStyle.getPropertyValue("width"); eventLeft = (Number(eventLeft.replace('px', '')) + Number(eventWidth.replace('px', '')) / 2).toString(); var scaleValue = Number(eventLeft) / totWidth; setTransformValue(filling.get(0), 'scaleX', scaleValue); } function setDatePosition(timelineComponents, min) { for (var i = 0; i < timelineComponents['timelineDates'].length; i++) { var distance = daydiff(timelineComponents['timelineDates'][0], timelineComponents['timelineDates'][i]), distanceNorm = Math.round(distance / timelineComponents['eventsMinLapse']) + 2; timelineComponents['timelineEvents'].eq(i).css('left', distanceNorm * min + 'px'); } } function setTimelineWidth(timelineComponents, width, selectedItemId) { var timeSpan = daydiff(timelineComponents['timelineDates'][0], timelineComponents['timelineDates'][timelineComponents['timelineDates'].length - 1]), timeSpanNorm = timeSpan / timelineComponents['eventsMinLapse'], timeSpanNorm = Math.round(timeSpanNorm) + 4, totalWidth = timeSpanNorm * width; timelineComponents['eventsWrapper'].css('width', totalWidth + 'px'); updateFilling(timelineComponents['eventsWrapper'].find('a#' + selectedItemId), timelineComponents['fillingLine'], totalWidth); updateTimelinePosition('next', timelineComponents['eventsWrapper'].find('a#' + selectedItemId), timelineComponents); return totalWidth; } function updateVisibleContent(event, eventsContent) { var eventId = event[0].id, visibleContent = eventsContent.find('.selected'), selectedContent = eventsContent.find('li#' + eventId), selectedContentHeight = selectedContent.height(); if (selectedContent.index() > visibleContent.index()) { var classEnetering = 'selected enter-right', classLeaving = 'leave-left'; } else { var classEnetering = 'selected enter-left', classLeaving = 'leave-right'; } selectedContent.attr('class', classEnetering); visibleContent.attr('class', classLeaving).one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function () { visibleContent.removeClass('leave-right leave-left'); selectedContent.removeClass('enter-left enter-right'); }); eventsContent.css('height', selectedContentHeight + 'px'); } function updateOlderEvents(event) { event.parent('li').prevAll('li').children('a').addClass('older-event').end().end().nextAll('li').children('a').removeClass('older-event'); } function getTranslateValue(timeline) { var timelineStyle = window.getComputedStyle(timeline.get(0), null), timelineTranslate = timelineStyle.getPropertyValue("-webkit-transform") || timelineStyle.getPropertyValue("-moz-transform") || timelineStyle.getPropertyValue("-ms-transform") || timelineStyle.getPropertyValue("-o-transform") || timelineStyle.getPropertyValue("transform"); if (timelineTranslate.indexOf('(') >= 0) { var timelineTranslate = timelineTranslate.split('(')[1]; timelineTranslate = timelineTranslate.split(')')[0]; var translateValue = timelineTranslate.split(',')[4]; } else { var translateValue = "0"; } return Number(translateValue); } function setTransformValue(element, property, value) { element.style["-webkit-transform"] = property + "(" + value + ")"; element.style["-moz-transform"] = property + "(" + value + ")"; element.style["-ms-transform"] = property + "(" + value + ")"; element.style["-o-transform"] = property + "(" + value + ")"; element.style["transform"] = property + "(" + value + ")"; } //based on http://stackoverflow.com/questions/542938/how-do-i-get-the-number-of-days-between-two-dates-in-javascript function parseDate(events) { var dateArrays = []; for (var i = 0; i < events.length; i++) { var dateComp = events[i].date.format("DD/MM/YYYY"); var dayComp = dateComp.split('/'); var timeComp = [0, 0]; var newDate = new Date(dayComp[2], dayComp[1] - 1, dayComp[0], timeComp[0], timeComp[1]); dateArrays.push(newDate); } return dateArrays; } function daydiff(first, second) { return Math.round((second - first)); } function minLapse(dates) { //determine the minimum distance among events var dateDistances = []; for (var i = 1; i < dates.length; i++) { var distance = daydiff(dates[i - 1], dates[i]); dateDistances.push(distance); } return Math.min.apply(null, dateDistances); } /* How to tell if a DOM element is visible in the current viewport? http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport */ function elementInViewport(el) { var top = el.offsetTop; var left = el.offsetLeft; var width = el.offsetWidth; var height = el.offsetHeight; while (el.offsetParent) { el = el.offsetParent; top += el.offsetTop; left += el.offsetLeft; } return ( top < (window.pageYOffset + window.innerHeight) && left < (window.pageXOffset + window.innerWidth) && (top + height) > window.pageYOffset && (left + width) > window.pageXOffset ); } function checkMQ() { //check if mobile or desktop device return window.getComputedStyle(document.querySelector('.cd-horizontal-timeline'), '::before').getPropertyValue('content').replace(/'/g, "").replace(/"/g, ""); }
timeline.component.html :
<div class="cd-horizontal-timeline mt-timeline-horizontal" data-spacing="60"> <div class="timeline"> <div class="events-wrapper"> <div class="events"> <ol> <li *ngFor="let timelineItem of timelineItems"> <a href="#0" id="{{timelineItem.id}}" class="border-after-red bg-after-red " [ngClass]="{'selected' : timelineItem.id===selectedItemId}"> <div> <i class="{{timelineItem.icon}}"></i> </div> <div> {{timelineItem.dateDisplay | date:'dd MMM'}} </div> </a> </li> </ol> <span class="filling-line bg-red" aria-hidden="true"></span> </div> </div> <ul class="cd-timeline-navigation mt-ht-nav-icon"> <li> <a href="#0" class="prev btn btn-danger"> test <i class="fa fa-chevron-left"></i> </a> </li> <li> <a href="#0" class="next btn btn-danger"> <i class="fa fa-chevron-right"></i> </a> </li> </ul> </div> <div class="events-content"> <ol> <li *ngFor="let timelineItem of timelineItems" [ngClass]="{'selected' : timelineItem.id===selectedItemId}" id="{{timelineItem.id}}"> <div class="mt-title"> <h2 class="mt-content-title"><i class="{{timelineItem.icon}}"></i> {{timelineItem.title}}</h2> </div> <div class="mt-author"> <div class="mt-author-name"> <a class="font-blue-madison">{{timelineItem.creatorName}}</a> </div> <div class="mt-author-datetime font-grey-mint">{{timelineItem.dateDisplay | date:'short'}}</div> </div> <div class="mt-content border-grey-steel"> <p>{{timelineItem.description}}</p> <a href="javascript:;" class="btn btn-primary" (click)="timelineItemClick(timelineItem)">{{timelineItem.buttonText}}</a> </div> </li> </ol> </div> </div>
and timeline.css to be added to angular.cli CSS imports
/*** Horizontal Timeline ***/ /* PLUGIN CSS */ .cd-horizontal-timeline { opacity: 0; -webkit-transition: opacity 0.2s; -moz-transition: opacity 0.2s; transition: opacity 0.2s; } .cd-horizontal-timeline::before { /* never visible - this is used in jQuery to check the current MQ */ content: 'mobile'; display: none; } .cd-horizontal-timeline.loaded { /* show the timeline after events position has been set (using JavaScript) */ opacity: 1; } .cd-horizontal-timeline .timeline { position: relative; height: 140px; width: 90%; max-width: 800px; margin: 0 auto; } .cd-horizontal-timeline .events-wrapper { position: relative; height: 100%; margin: 0 40px; overflow: hidden; } .cd-horizontal-timeline .events-wrapper::after, .cd-horizontal-timeline .events-wrapper::before { /* these are used to create a shadow effect at the sides of the timeline */ content: ''; position: absolute; z-index: 2; top: 0; height: 100%; width: 20px; } .cd-horizontal-timeline .events-wrapper::before { left: 0; background-image: -webkit-linear-gradient(left, #f8f8f8, rgba(248, 248, 248, 0)); background-image: linear-gradient(to right, #f8f8f8, rgba(248, 248, 248, 0)); } .cd-horizontal-timeline .events-wrapper::after { right: 0; background-image: -webkit-linear-gradient(right, #f8f8f8, rgba(248, 248, 248, 0)); background-image: linear-gradient(to left, #f8f8f8, rgba(248, 248, 248, 0)); } .cd-horizontal-timeline .events { /* this is the grey line/timeline */ position: absolute; z-index: 1; left: 0; top: 69px; height: 2px; /* width will be set using JavaScript */ background: #dfdfdf; -webkit-transition: -webkit-transform 0.4s; -moz-transition: -moz-transform 0.4s; transition: transform 0.4s; } .cd-horizontal-timeline .filling-line { /* this is used to create the green line filling the timeline */ position: absolute; z-index: 1; left: 0; top: 0; height: 100%; width: 100%; background-color: #f4516c; -webkit-transform: scaleX(0); -moz-transform: scaleX(0); -ms-transform: scaleX(0); -o-transform: scaleX(0); transform: scaleX(0); -webkit-transform-origin: left center; -moz-transform-origin: left center; -ms-transform-origin: left center; -o-transform-origin: left center; transform-origin: left center; -webkit-transition: -webkit-transform 0.3s; -moz-transition: -moz-transform 0.3s; transition: transform 0.3s; } .cd-horizontal-timeline .events a { position: absolute; bottom: 0; z-index: 2; text-align: center; font-size: 1rem; padding-bottom: 15px; color: [#383838](https://support.aspnetzero.com/QA/Questions/383838); /* fix bug on Safari - text flickering while timeline translates */ -webkit-transform: translateZ(0); -moz-transform: translateZ(0); -ms-transform: translateZ(0); -o-transform: translateZ(0); transform: translateZ(0); } .cd-horizontal-timeline .events a::after { /* this is used to create the event spot */ content: ''; position: absolute; left: 50%; right: auto; -webkit-transform: translateX(-50%); -moz-transform: translateX(-50%); -ms-transform: translateX(-50%); -o-transform: translateX(-50%); transform: translateX(-50%); bottom: -5px; height: 12px; width: 12px; border-radius: 50%; -webkit-transition: background-color 0.3s, border-color 0.3s; -moz-transition: background-color 0.3s, border-color 0.3s; transition: background-color 0.3s, border-color 0.3s; } .no-touch .cd-horizontal-timeline .events a:hover::after { background-color: #7b9d6f; border-color: #7b9d6f; } .cd-horizontal-timeline .events a.selected { pointer-events: none; } @media only screen and (min-width: 1100px) { .cd-horizontal-timeline::before { /* never visible - this is used in jQuery to check the current MQ */ content: 'desktop'; } } .cd-timeline-navigation a { /* these are the left/right arrows to navigate the timeline */ position: absolute; z-index: 1; top: 50%; bottom: auto; -webkit-transform: translateY(-50%); -moz-transform: translateY(-50%); -ms-transform: translateY(-50%); -o-transform: translateY(-50%); transform: translateY(-50%); height: 34px; width: 34px; border-radius: 50%; /* replace text with an icon */ overflow: hidden; text-indent: 100%; white-space: nowrap; -webkit-transition: border-color 0.3s; -moz-transition: border-color 0.3s; transition: border-color 0.3s; } .cd-timeline-navigation a.prev { left: 0; } .cd-timeline-navigation a.next { right: 0; } .cd-timeline-navigation a.inactive { cursor: not-allowed; } .cd-timeline-navigation a.inactive::after { background-position: 0 -16px; } .cd-horizontal-timeline .events-content { position: relative; width: 100%; margin: 10px 0 0 0; overflow: hidden; -webkit-transition: height 0.4s; -moz-transition: height 0.4s; transition: height 0.4s; } .cd-horizontal-timeline .events-content > ol > li { position: absolute; z-index: 1; width: 100%; left: 0; top: 0; -webkit-transform: translateX(-100%); -moz-transform: translateX(-100%); -ms-transform: translateX(-100%); -o-transform: translateX(-100%); transform: translateX(-100%); padding: 0; opacity: 0; -webkit-animation-duration: 0.4s; -moz-animation-duration: 0.4s; animation-duration: 0.4s; -webkit-animation-timing-function: ease-in-out; -moz-animation-timing-function: ease-in-out; animation-timing-function: ease-in-out; } .cd-horizontal-timeline .events-content > ol > li.selected { /* visible event content */ position: relative; z-index: 2; opacity: 1; -webkit-transform: translateX(0); -moz-transform: translateX(0); -ms-transform: translateX(0); -o-transform: translateX(0); transform: translateX(0); } .cd-horizontal-timeline .events-content > ol > li.enter-right, .cd-horizontal-timeline .events-content > ol > li.leave-right { -webkit-animation-name: cd-enter-right; -moz-animation-name: cd-enter-right; animation-name: cd-enter-right; } .cd-horizontal-timeline .events-content > ol > li.enter-left, .cd-horizontal-timeline .events-content > ol > li.leave-left { -webkit-animation-name: cd-enter-left; -moz-animation-name: cd-enter-left; animation-name: cd-enter-left; } .cd-horizontal-timeline .events-content > ol > li.leave-right, .cd-horizontal-timeline .events-content > ol > li.leave-left { -webkit-animation-direction: reverse; -moz-animation-direction: reverse; animation-direction: reverse; } .cd-horizontal-timeline .events-content > ol > li { margin: 0 auto; } .cd-horizontal-timeline .events-content em { display: block; font-style: italic; margin: 10px auto; } .cd-horizontal-timeline .events-content em::before { content: '- '; } @-webkit-keyframes cd-enter-right { 0% { opacity: 0; -webkit-transform: translateX(100%); } 100% { opacity: 1; -webkit-transform: translateX(0%); } } @-moz-keyframes cd-enter-right { 0% { opacity: 0; -moz-transform: translateX(100%); } 100% { opacity: 1; -moz-transform: translateX(0%); } } @keyframes cd-enter-right { 0% { opacity: 0; -webkit-transform: translateX(100%); -moz-transform: translateX(100%); -ms-transform: translateX(100%); -o-transform: translateX(100%); transform: translateX(100%); } 100% { opacity: 1; -webkit-transform: translateX(0%); -moz-transform: translateX(0%); -ms-transform: translateX(0%); -o-transform: translateX(0%); transform: translateX(0%); } } @-webkit-keyframes cd-enter-left { 0% { opacity: 0; -webkit-transform: translateX(-100%); } 100% { opacity: 1; -webkit-transform: translateX(0%); } } @-moz-keyframes cd-enter-left { 0% { opacity: 0; -moz-transform: translateX(-100%); } 100% { opacity: 1; -moz-transform: translateX(0%); } } @keyframes cd-enter-left { 0% { opacity: 0; -webkit-transform: translateX(-100%); -moz-transform: translateX(-100%); -ms-transform: translateX(-100%); -o-transform: translateX(-100%); transform: translateX(-100%); } 100% { opacity: 1; -webkit-transform: translateX(0%); -moz-transform: translateX(0%); -ms-transform: translateX(0%); -o-transform: translateX(0%); transform: translateX(0%); } } /* METRONIC EXTENDED CSS */ .mt-timeline-horizontal { font-size: 14px; } .mt-timeline-horizontal ol, .mt-timeline-horizontal ul { list-style: none; } .mt-timeline-horizontal blockquote, .mt-timeline-horizontal q { quotes: none; } .mt-timeline-horizontal blockquote:before, .mt-timeline-horizontal blockquote:after, .mt-timeline-horizontal q:before, .mt-timeline-horizontal q:after { content: ''; content: none; } .mt-timeline-horizontal table { border-collapse: collapse; border-spacing: 0; } .mt-timeline-horizontal .timeline { width: 100%; max-width: 100%; } .mt-timeline-horizontal .timeline:before { background: transparent; } .mt-timeline-horizontal .timeline .events-wrapper .events a:after { background-color: #fff; border: 2px solid; } .mt-timeline-horizontal .timeline .events-wrapper .events a.selected:after { background-color: #fff !important; } .mt-timeline-horizontal .timeline .events-wrapper .events a:hover, .mt-timeline-horizontal .timeline .events-wrapper .events a:focus { text-decoration: none; } .mt-timeline-horizontal .timeline .events-wrapper:before, .mt-timeline-horizontal .timeline .events-wrapper:after { background-image: none; } .mt-timeline-horizontal .timeline .mt-ht-nav-icon li a { border-radius: 50% !important; } .mt-timeline-horizontal .timeline .mt-ht-nav-icon li a i { position: absolute; top: 50%; left: 8px; transform: translateX(50%) translateY(-50%); width: 10px; } .mt-timeline-horizontal .timeline .mt-ht-nav-icon li:first-child a i { left: 5px; } .mt-timeline-horizontal .timeline.mt-timeline-square .events a:after { border-radius: 0 !important; } .mt-timeline-horizontal .timeline.mt-timeline-square .mt-ht-nav-icon li a { border-radius: 0 !important; } .mt-timeline-horizontal .events-content ol { padding: 0; } .mt-timeline-horizontal .events-content ol li .mt-title { margin-top: 15px; float: left; width: 60%; } .mt-timeline-horizontal .events-content ol li .mt-title h2 { margin: 0; opacity: 0.8 ; filter: alpha(opacity=80) ; font-size: 18px; font-weight: 600; } .mt-timeline-horizontal .events-content ol li .mt-author { float: right; position: relative; text-align: right; width: 40%; } .mt-timeline-horizontal .events-content ol li .mt-author > .mt-avatar { float: right; margin-left: 15px; } .mt-timeline-horizontal .events-content ol li .mt-author > .mt-author-name { margin-top: 5px; } .mt-timeline-horizontal .events-content ol li .mt-author > .mt-author-name a { opacity: 0.9 ; filter: alpha(opacity=90) ; font-size: 15px; font-weight: 600; } .mt-timeline-horizontal .events-content ol li .mt-author > .mt-author-name a:hover, .mt-timeline-horizontal .events-content ol li .mt-author > .mt-author-name a:focus { text-decoration: none; } .mt-timeline-horizontal .events-content ol li .mt-author > .mt-author-datetime { font-size: 13px; } .mt-timeline-horizontal .events-content ol li .mt-author > .mt-avatar { width: 50px; height: 50px; border-radius: 50% !important; overflow: hidden; } .mt-timeline-horizontal .events-content ol li .mt-author > .mt-avatar > img { width: 100%; height: auto; } .mt-timeline-horizontal .events-content ol li .mt-content { margin-top: 20px; padding-top: 20px; border-top: 1px solid; clear: both; line-height: 1.7em; } .mt-timeline-horizontal .events-content ol li .mt-content > p { opacity: 0.7 ; filter: alpha(opacity=70) ; } .mt-timeline-horizontal .events-content ol li .mt-content img.pull-left { margin: 0 15px 15px 0; } .mt-timeline-horizontal .events-content ol li .mt-content img.pull-right { margin: 0 0 15px 15px; } .mt-timeline-horizontal .events-content ol li .mt-content .btn-group .dropdown-menu { margin-right: 5px; } @media (max-width: 480px) { .mt-timeline-horizontal .events-content ol li .mt-title { width: 100%; } .mt-timeline-horizontal .events-content ol li .mt-author { width: 100%; margin-top: 15px; text-align: left; } .mt-timeline-horizontal .events-content ol li .mt-author > .mt-avatar { float: left; margin-right: 15px; margin-left: 0; } .mt-timeline-horizontal .events-content ol li .mt-author > .mt-author-name { margin-top: 10px; } .mt-timeline-horizontal .btn.pull-right { float: none !important; margin: 0 !important; } }
-
0
Thanks a lot @Ricavir :),
I have created an issue for this <a class="postlink" href="https://github.com/aspnetzero/aspnet-zero-core/issues/697">https://github.com/aspnetzero/aspnet-ze ... issues/697</a>.