How to style content rendered with ngx-markdown? - css

I'm building a blog with Angular and I want to create my posts with Markdown. I intend to use ngx-markdown to render them. Right now I'm creating a "post creation" component. The thing is I wish to apply some styling on the markdown, but I can't. This is my component:
<div class="header-container">
<h1 class="header">New post</h1>
<button>Send</button>
</div>
<div class="main-container">
<div class="post-editor">
<label for="title">Title:</label>
<input class="title-field" type="text" name="title"
placeholder="E.g: Introduction to Programming" autocomplete="off"
[(ngModel)]="post.title"
>
<textarea [(ngModel)]="post.content"></textarea>
</div>
<div class="post-preview">
<markdown class="markdown" [data]="getPostAsString()" ngPreserveWhitespaces>
</markdown>
</div>
</div>
import { Component, OnInit } from '#angular/core';
interface Post {
title: string;
content: string;
}
#Component({
selector: 'app-create-post',
templateUrl: './create-post.component.html',
styleUrls: ['./create-post.component.css']
})
export class CreatePostComponent implements OnInit {
post: Post = {
title: 'Introduction to Programming',
content: 'Lorem ipsum dolor, sit amet...'
};
constructor() {
}
ngOnInit(): void {
}
getPostAsString(): string {
return `# ${this.post.title}\n` + this.post.content;
}
}
h1 {
margin-top: 20px;
color: blue;
}
label {
font-size: 18px;
}
input, textarea {
width: 100%;
}
input {
height: 25px;
}
textarea {
height: 300px;
}
button {
margin-left: auto;
height: 75%;
align-self: center;
font-size: 18px;
padding: 5px 10px;
}
.header-container, .main-container {
display: flex;
}
.post-editor, .post-preview {
flex: 1;
}
.post-preview {
padding-top: 20px;
}
.post-editor {
margin-right: 40px;
}
.header {
margin-bottom: 25px;
}
.title-field {
display: block;
margin-top: 5px;
margin-bottom: 20px;
}
Note this rule:
h1 {
color: blue;
}
I applied it for test purposes. The header on top of the page that says "New Post" gets styled (blue), but the markdown one does not. I also tried using different selectors such as markdown h1 and .post-preview h1, but none worked. Why it isn't working and how can I make it work?

Generally libray css changes is working in styles.css you should try to add you css code block to styles.css
.post-preview h1 {
color: blue;
}

If you are using Angular you can apply the styles when you use ::ng-deep:
.post-preview ::ng-deep h1 {
color: blue;
}

Related

Importing bootstrap breaks Navigation bar

My project is running on vue3.
I have a Side navigation bar which consists of navigation links, it works well until I import bootstrap, which causes the icons to shift slightly and the buttons become smaller in size. I've tried the same with tailwind and the same issue occurs. The exact line that breaks it is the import of bootstraps min css file. (import "bootstrap/dist/css/bootstrap.min.css", inside of main.js).Below are screenshots and snippets of code for the navigation bar.
<script>
import NavBarLink from './NavBarLink.vue'
import {collapsed, toggleNavbar, navbarWidth} from './state'
export default{
props: {},
setup() {
return { collapsed, toggleNavbar, navbarWidth };
},
components: { NavBarLink }
}
</script>
<template>
<div class="sidebar" :style="{ width: navbarWidth }">
<span #click="toggleNavbar" style="margin-bottom: 15px;">
<i :class="`${collapsed ? 'fa-solid fa-bars': 'fa-solid fa-x'}`"></i>
</span>
<span v-if="!collapsed" class="logo">website.<span style="color: orange">club</span></span>
<span v-else class="logo">w<span style="color: orange">w</span></span>
<NavBarLink to="/about" icon="fa-solid fa-magnifying-glass">Search</NavBarLink>
<NavBarLink to="/plans" icon="fa-solid fa-tag">Plans</NavBarLink>
<NavBarLink to="/fart" icon="fa-solid fa-user">Profile</NavBarLink>
</div>
</template>
<style>
:root {
--navbar-bg-color: #0e0e0e;
--navbar-item-hover: #1d1d1d;
}
</style>
<style scoped>
.sidebar{
color: white;
background-color: var(--navbar-bg-color);
float: left;
position: fixed;
z-index: 1;
top: 0;
bottom: 0;
left: 0;
bottom: 0;
padding: 0.5rem;
transition: 0.3s ease;
display: flex;
flex-direction: column;
}
.logo {
font-size: larger;
font-family: Nexa;
padding-top:15px;
padding-bottom:15px;
}
</style>
<script>
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import { collapsed } from './state'
export default {
props: {
to: { type: String, required: true },
icon: { type: String, required: true }
},
setup(props) {
const route = useRoute()
const isActive = computed(() => route.path === props.to)
return { isActive, collapsed }
}
}
</script>
<template>
<router-link :to="to" class="link" :class="{ active: isActive }">
<i class="icon" :class="icon"/>
<transition name="fade">
<span v-if="!collapsed">
<slot/>
</span>
</transition>
</router-link>
</template>
<style scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.1s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.link {
display: flex;
align-items: center;
cursor: pointer;
position: relative;
font-weight: 400;
user-select: none;
margin: 0.1em 0.1em;
padding: 0.4em;
border-radius: 0.25em;
height: 1.7em;
color: white;
text-decoration: none;
}
.link:hover {
transition: .17s;
background-color: var(--navbar-item-hover);
}
.link.active {
background-color: var(--navbar-item-hover);
}
.link .icon {
flex-shrink: 0;
width: 35px;
margin-right: 10px;
}
</style>
Is there a bootstrap component I can remove to make this function?

Centering a div with css in nextjs (moves but doesn't completely center)

I have tried looking at many questions on StackOverflow and none of them have helped me. I think that I have a more specific problem, there might be some type of CSS attribute that is stopping the div from centering. Maybe I need to use flexbox to solve this?
here is the JSX:
import { useState } from 'react'
import styles from '../styles/login.module.css'
import Head from 'next/head'
export default function Login() {
const [loginDetails, setLoginDetails] = useState({username: "", password: ""});
function handleUsernameChange(e) {
var value = e.target.value;
setLoginDetails({username: value, password: loginDetails.password});
}
function handlePasswordChange(e) {
var value = e.target.value;
setLoginDetails({username: loginDetails.username, password: value});
}
function SubmitLogin() {
console.log(loginDetails);
}
return (
<>
<Head>
<title>Login</title>
</Head>
<div className={styles.container}>
<h1 className={styles.subheading}>Login</h1>
<label>Username:</label>
<input type="text" placeholder="username" className={styles.input} onChange={handleUsernameChange} />
<label>Password:</label>
<input type="password" placeholder="password" className={styles.input} onChange={handlePasswordChange} />
<button className={styles.button} onClick={SubmitLogin}>Login</button>
</div>
</>
);
}
Here is the CSS:
.heading {
font-size: 3rem;
}
.subheading {
font-size: 2rem;
}
.pheading {
font-size: 1.5rem;
}
.paragraph {
margin-left: 1rem;
}
.container {
display: flex;
flex-direction: column;
gap: 10px;
margin: 0 auto;
width: 25%;
}
.input {
border-radius: 5px;
max-width: 200px;
height: 30px;
border: 1px solid #d7dbd9;
}
.input:focus {
outline: none;
border: 1px solid #67f0ab;
}
.button {
border: 2px solid #67f0ab;
border-radius: 5px;
color: #67f0ab;
background: none;
max-width: 100px;
height: 30px;
}
.button:hover {
background-color: #67f0ab;
color: #FFF;
}
.button:active {
background-color: #49de93;
}
The element I am trying to center is the div wrapping the login form. It has the class of .container, this class is what I was editing in my CSS to try and solve the problem. I can get the element to move to different spots, but I can't center it.
Ok so I figured out what the problem was, it was that the max-width of my container was larger than that of my widest element inside of the container, in this case it happened to be the inputs
I changed the max-width value of my container to 200px which is the same as my .input class, and the container and all of its elements were then centered.

How to dynamically change the size of icon in <IconContext.Provider>

currently, to style my icons under the 'react-icons' library, I am using the 'IconContext.Provider' tag. However, is there a solution for me to change the size of the icon dynamically based on the size of my media ?
Is the only solution to go about doing this only with the global stylesheet? I am avoiding it as I have only just started using NextJs and I do not want my style to have a possible clash with other style. Hence, I am separating them into modules.
Thank you.
NavBar.Module.Css
#import url("https://fontlibrary.org//face/metropolis");
.siteTitleWrapper {
box-sizing: border-box;
display: table-cell;
vertical-align: middle;
}
.siteTitle {
font-family: "MetropolisRegular";
font-weight: 600;
font-style: normal;
font-size: 20px;
letter-spacing: 2px;
text-transform: uppercase;
color: #000;
margin: 0;
padding-top: 0;
padding-bottom: 0;
line-height: 1em;
white-space: nowrap;
}
.headerInner {
padding: 20px 0;
display: table;
width: 100%;
}
.mainNavigation {
text-align: right;
position: relative;
z-index: 1000;
display: block;
}
.NavItemsWrapper {
display: inline-flex;
align-items: center;
overflow: hidden;
cursor: pointer;
}
.NavItems {
font: "MetropolisRegular";
font-weight: 600;
font-style: normal;
font-size: 13px;
letter-spacing: 2px;
text-transform: uppercase;
text-decoration: none;
}
#media only screen and (max-width: 830px) {
.mainNavigation {
-webkit-font-smoothing: subpixel-antialiased;
display: inline-flexbox;
position: fixed;
bottom: 64px;
left: 0;
height: auto;
width: 100%;
background-color: #f7f7f7;
overflow: hidden;
text-align: center;
vertical-align: top;
}
.NavItems {
display: none;
}
}
NavBar.tsx
import Link from 'next/link'
import styles from '../styles/components/NavBar.module.css'
import {HiHome} from 'react-icons/hi'
import {FaBloggerB} from 'react-icons/fa'
import {AiOutlineFundProjectionScreen} from 'react-icons/ai'
import {BsPersonBadge} from 'react-icons/bs'
import {IconContext} from 'react-icons'
import { IconType } from 'react-icons/lib'
interface navItemsTypes {
icon: IconType,
category: string,
link: string
}
const navItems : navItemsTypes[] = [
{icon: HiHome, category: 'Home', link: '/'},
{icon: AiOutlineFundProjectionScreen, category: 'Projects', link: '/projects'},
{icon: FaBloggerB, category: 'Blogs', link: '/blogs'},
{icon: BsPersonBadge, category: 'About', link: '/about'},
]
const NavBar = () => {
return (
<div>
<nav className={styles.headerInner}>
<div className={styles.siteTitleWrapper}>
<h1 id="site-title" className={styles.siteTitle} ><Link href='/'>Hong Sheng Yang</Link></h1>
</div>
<div className={styles.mainNavigation}>
<IconContext.Provider value={{ size: '1em', style:{marginLeft:'3em',marginRight:'0.5em', color:'#000'}}}>
{navItems.map((item) => (
<div className={styles.NavItemsWrapper}>
<Link href={item.link}>
<span style={{display:'flex'}}>
<item.icon/>
<p className={styles.NavItems}>
{item.category}
</p>
</span>
</Link>
</div>
))}
</IconContext.Provider>
</div>
</nav>
</div>
)
}
export default NavBar
I did "npm i react-responsive" and import the following in my code
import { useMediaQuery } from 'react-responsive'
Additionally, I declared the sizes for mobile and phone with 2 const
const phoneViewNav = {
size: '1em',
}
const DesktopViewNav = {
size: '1.5em',
}
Lastly, I use the media query to check for the screen size and apply accordingly
const NavBar = () => {
const isDesktopOrLaptop = useMediaQuery({maxWidth:830})
const iconSize = isDesktopOrLaptop ? phoneViewNav : DesktopViewNav
const router = useRouter();
return (
<div id="nav">
....
<IconContext.Provider value={{ size: iconSize.size, style:{color:"#000"}}}> ...
</div> )}

Positive elements are relative to the page, not the parent React component

I have a DeleteWindow Rect-component that resides in a Post component. I want the element window to be centered on the screen, not centered on the parent component. I used all my knowledge of css to position relative to the screen, but the component is still positioned relative to the parent component and cannot go beyond it. Tell me how to fix this situation
import React from 'react';
import {postApi} from "./../utils/api"
import {DeleteWindow} from "./DeleteWindow"
export class Post extends React.Component{
constructor(props) {
super(props);
this.state = {
onDelete: false
}
this.removePost = this.removePost.bind(this);
this.redactPost = this.redactPost.bind(this);
this.callbackRemove = this.callbackRemove.bind(this);
}
removePost(){
this.setState({onDelete: true});
}
callbackRemove(isRemove){
this.setState({onDelete: false});
if(isRemove)
this.props.onRemove(this.props.id);
}
redactPost(){
postApi.setUpdatePost({id: this.props.id, title: this.props.title, text: this.props.text, author: this.props.author}).then(window.location.assign("/redactPost"));
}
render() {
function EditButton(props){
if (props.admin){
return(
<>
<h className="editButton" onClick={props.redactPost}>
Изменить
</h>
<h className="removeButton" onClick={props.removePost}>
Удалить
</h>
</>
);
}
return null;
}
function DeleteBlock(props){
if (props.onDelete)
return <DeleteWindow onDelete={props.onDelete} callbackRemove={props.callbackRemove}/>
return null;
}
return(
<div>
<DeleteBlock onDelete={this.state.onDelete} callbackRemove={this.callbackRemove}/>
<hr/>
<div className="post">
<p className="titlePost">{this.props.title}</p>
<p className="textPost">{this.props.text}</p>
<p className="author">{this.props.author}</p>
<p className="center">
<p>
<i className="date">{this.props.date}</i>
<EditButton admin={this.props.admin} redactPost={this.redactPost} removePost={this.removePost}/>
</p>
</p>
</div>
</div>
)
}
}
import React from 'react';
export class DeleteWindow extends React.Component{
constructor(props) {
super(props);
this.clickYes = this.clickYes.bind(this);
this.clickNo = this.clickNo.bind(this);
}
clickYes(){
this.props.callbackRemove(true);
}
clickNo(){
this.props.callbackRemove(false);
}
render(){
return(
<div className="deleteBlock">
<p>Вы действительно хотите удалить этот пост?</p>
<button className="deleteWindowButton" onClick={this.clickYes}>Да</button>
<button className="deleteWindowButton" onClick={this.clickNo}>Нет</button>
</div>
);
}
}
#media (min-width: 850px) {
.deleteBlock {
width: 40%;
font-size: 16pt;
margin-left: 30%;
}
.deleteWindowButton{
width: 30%;
font-size: 15pt;
}
}
#media (max-width: 850px) and (min-width: 580px) {
.deleteBlock {
width: 60%;
font-size: 14pt;
margin-left: 20%;
}
.deleteWindowButton{
width: 30%;
font-size: 13pt;
}
}
#media (max-width: 580px) and (min-width: 400px) {
.deleteBlock {
width: 80%;
font-size: 13pt;
margin-left: 10%;
}
.deleteWindowButton{
width: 30%;
font-size: 12pt;
}
}
#media (max-width: 400px){
.deleteBlock {
width: 90%;
font-size: 12pt;
margin-left: 5%;
}
.deleteWindowButton{
width: 30%;
font-size: 11pt;
}
}
.deleteBlock{
position: fixed;
text-align: center;
background-color: #676a6d;
font-family: "Lucida Calligraphy", cursive;
border-radius: 20px;
border: 2px solid black;
z-index: 1;
}
.deleteWindowButton{
border-radius: 20px;
padding: 1%;
margin: 1%;
outline: none;
}
.deleteWindowButton:hover{
cursor: pointer;
}

Adding a colour class to an element in scss based on existence of element

I have an article block that looks like this:
The SCSS for this box is here:
/* Styling for all articles on index page */
#news-grid {
.article {
margin: 0px;
text-align: left;
border: none;
.article-featured-image-box {
position: relative;
.featured-image {
max-width: 100%;
height: auto;
display: block;
position: relative;
width: 100%;
object-fit: cover;
}
}
.article-meta-information {
color: #cacacd;
font-size: 15px;
font-family: $balto-font;
font-weight: 300;
border-bottom: 1px solid #f0f0f0;
padding-bottom: 5px;
}
.article-content {
padding: 30px 30px 30px 30px;
background-color: #ffffff;
}
.article-title {
font-family: $circular-font;
color: $newable-navy;
font-size: 24px;
font-weight: 500;
margin-top: 10px;
margin-bottom: 10px;
word-wrap: break-word;
a {
color: $newable-navy;
}
}
.article-body {
line-height: 24px;
font-family: $balto-font;
font-size: 18px;
font-weight: 300;
p {
line-height: 24px;
font-family: $balto-font;
color: $newable-dark-grey;
font-size: 18px;
font-weight: 300;
word-wrap: break-word;
a {
color: $newable-blue;
}
}
a {
color: $newable-blue;
}
.article-excerpt p {
line-height: 24px;
font-family: CircularStd;
color: $newable-navy;
font-size: 21px;
font-weight: 500;
word-wrap: break-word;
}
}
.article-footer {
padding-top: 15px;
border-top: 1px solid $newable-grey;
padding-bottom: 30px;
}
.interactions-panel {
width: auto;
float: right;
}
.sticker {
background-color: #fff;
background-color: rgba(255, 255, 255, 0.92);
text-transform: uppercase;
font-size: 12px;
line-height: 18px;
color: #282C35;
-webkit-box-sizing: border-box;
box-sizing: border-box;
position: absolute;
display: inline-block;
top: 0px;
right: 0px;
height: 45px;
width: 45px;
}
}
}
What I'm looking to do is add a class that dictates colour, for instance, if an image is not provided I want the news article to have a dark theme.
This class .dark will change the background colour, text colour and title colour.
The articles are generated using a foreach loop
#foreach($articles as $article)
<div class="grid-item element-item {{ str_slug($article->category) }}">
<div class="article">
<div class="article-featured-image-box">
#if($article->featuredVideo != NULL)
{!! $article->featuredVideo !!}
#else
<img class="featured-image" style="width: 100%; height:auto;" src="{{ $article->featuredImage }}" alt="{{ $article->title }}">
#endif
#if($article->featuredArticle)
<div class="sticker yellow">
<span class="icon icon-news"></span>
</div>
#endif
</div>
<div class="article">
<div class="article-content">
<div class="article-meta-information">
{{ $article->created_at->format('d F Y') }} | {{ $article->author }}
</div>
<div class="article-title">
{{ $article->title }}
</div>
<div class="article-body">
<p>{{ $article->excerpt }}</p>
</div>
</div>
</div>
</div>
</div>
#endforeach
At the top of the foreach I can check if there is a featured image and redefine <div class="article"> to <div class="article dark">
Is there a way in SaSS that I can say if the class is .article .dark change the colours of the inner elements, or would I have to have a separate bunch of styling?
Also, would you just hide the featured image box or redefine the whole block?
I'd essentially like to be able to have many themes for the article block in which I can append a class to control the colouring.
This is probably really simple but I've hit a wall
You could add a aggregate class to the .article class using &:
#news-grid {
.article {
// Your current styles and nested classes...
// When .article.dark
&.dark {
// Your custom overrides
.article-title {
color: white;
}
}
}
}
I built a working compilation example here. Note that i added some variables at the top just to make the code work.
Hope it helps.
This seems like a good use for Sass maps.
You could create your two themes (light and dark) as maps, then use them in a mixin, switching themes by passing an argument to the mixin. For example:
// All styles for .article go here
#mixin article($theme) {
background-color: map-get($theme, main-bg);
.article-title {
color: map-get($theme, title-col);
}
}
// Colours stored as Sass maps
$theme--light: (
main-bg: gainsboro,
title-col: dimgrey
);
$theme--dark: (
main-bg: darkslategrey,
title-col: whitesmoke
);
// Finally, here we call the mixin, passing name of the correct map
.article {
#include article($theme--light);
}
.article.dark {
#include article($theme--dark);
}
This compiles to:
.article {
background-color: gainsboro;
}
.article .article-title {
color: dimgrey;
}
.article.dark {
background-color: darkslategrey;
}
.article.dark .article-title {
color: whitesmoke;
}

Resources