li

Cobalt–carbon/silica nanocomposites prepared by pyrolysis of a cobalt 2,2'-bipyridine terephthalate complex for remediation of cationic dyes

RSC Adv., 2020, 10,17660-17672
DOI: 10.1039/D0RA02752A, Paper
Open Access
Nusaybah Alotaibi, Hassan H. Hammud, Ranjith Kumar Karnati, Syed Ghazanfar Hussain, Javed Mazher, Thirumurugan Prakasam
A cobalt–carbon@silica nanocomposite was synthesized from a cobalt 2,2'-bipyridine terephthalate complex and its adsorption behavior towards crystal violet dye was tested using batch and column techniques.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

A facile method for preparing Yb3+-doped perovskite nanocrystals with ultra-stable near-infrared light emission

RSC Adv., 2020, 10,17635-17641
DOI: 10.1039/D0RA01897J, Paper
Open Access
Chunqian Zhang, Aidi Zhang, Taoran Liu, Lin Zhou, Jun Zheng, Yuhua Zuo, Yongqi He, Juhao Li
A facile method for fabricating CsPbBr3:Yb3+@SiO2 NCs which guarantees high PLQY and excellent stability at the same time.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Novel lightweight open-cell polypropylene foams for filtering hazardous materials

RSC Adv., 2020, 10,17694-17701
DOI: 10.1039/D0RA01499K, Paper
Open Access
Fei Wu, Pengke Huang, Haibin Luo, Jin Wang, Bin Shen, Qian Ren, Pei He, Hao Zheng, Liyang Zhang, Wenge Zheng
Lightweight polypropylene foams with similar geometries but different porous structures were prepared as filters for potentially hazardous materials via supercritical CO2 extrusion foaming without the use of harmful reagents and the problems of floating micro-nano fibers.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Correction: Role of polysilicon in poly-Si/SiOx passivating contacts for high-efficiency silicon solar cells

RSC Adv., 2020, 10,17571-17571
DOI: 10.1039/D0RA90049D, Correction
Open Access
  This article is licensed under a Creative Commons Attribution 3.0 Unported Licence.
HyunJung Park, Soohyun Bae, Se Jin Park, Ji Yeon Hyun, Chang Hyun Lee, Dongjin Choi, Dongkyun Kang, Hyebin Han, Yoonmook Kang, Hae-Seok Lee, Donghwan Kim
The content of this RSS Feed (c) The Royal Society of Chemistry




li

One-pot oxime ligation from peptides bearing thiazolidine and aminooxyacetyl groups

RSC Adv., 2020, 10,17681-17685
DOI: 10.1039/D0RA03235B, Paper
Open Access
Stéphane Duflocq, Jingjing Zhou, Florent Huguenot, Michel Vidal, Wang-Qing Liu
Pd(II), acidic hydrolysis and iodine lead to one-pot oxime ligation from peptides bearing thiazolidine and aminooxyacetyl groups.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Mechanochemical approach to synthesize citric acid-soluble fertilizer of dittmarite (NH4MgPO4·H2O) from talc/NH4H2PO4 mixture

RSC Adv., 2020, 10,17686-17693
DOI: 10.1039/D0RA00387E, Paper
Open Access
Yonghao Tan, Lin Sha, Nengkui Yu, Zhengshuo Yang, Jun Qu, Zhigao Xu
Dittmarite synthesis by a mechanochemical route for application as a citric acid-soluble fertilizer.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

A novel series of phenolic temozolomide (TMZ) esters with 4 to 5-fold increased potency, compared to TMZ, against glioma cells irrespective of MGMT expression

RSC Adv., 2020, 10,17561-17570
DOI: 10.1039/D0RA02686G, Paper
Open Access
  This article is licensed under a Creative Commons Attribution 3.0 Unported Licence.
Leroy Shervington, Oliver Ingham, Amal Shervington
The standard of care treatment for patients diagnosed with glioblastoma multiforme (GBM) is temozolomide (TMZ).
The content of this RSS Feed (c) The Royal Society of Chemistry




li

A highly sensitive, selective and renewable carbon paste electrode based on a unique acyclic diamide ionophore for the potentiometric determination of lead ions in polluted water samples

RSC Adv., 2020, 10,17552-17560
DOI: 10.1039/D0RA01435D, Paper
Open Access
  This article is licensed under a Creative Commons Attribution 3.0 Unported Licence.
M. A. Zayed, Walaa H. Mahmoud, Ashraf A. Abbas, Aya E. Ali, Gehad G. Mohamed
Due to the toxicity of lead(II) to all living organisms destroying the central nervous system and leading to circulatory system and brain disorders, the development of effective and selective lead(II) ionophores for its detection is very important.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Selective cytotoxic effect against the MDA-MB-468 breast cancer cell line of the antibacterial palindromic peptide derived from bovine lactoferricin

RSC Adv., 2020, 10,17593-17601
DOI: 10.1039/D0RA02688C, Paper
Open Access
Andrea Barragán-Cárdenas, Maribel Urrea-Pelayo, Víctor Alfonso Niño-Ramírez, Adriana Umaña-Pérez, Jean Paul Vernot, Claudia Marcela Parra-Giraldo, Ricardo Fierro-Medina, Zuly Rivera-Monroy, Javier García-Castañeda
The cytotoxic effect against the breast cancer cell line MDA-MB-468 of the palindromic peptide LfcinB (21–25)Pal: 1RWQWRWQWR9 and its analogous peptides, obtained via alanine scanning, was evaluated.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Correction: Influence of co-cultures of Streptococcus thermophilus and probiotic lactobacilli on quality and antioxidant capacity parameters of lactose-free fermented dairy beverages containing Syzygium cumini (L.) Skeels pulp

RSC Adv., 2020, 10,16905-16905
DOI: 10.1039/D0RA90046J, Correction
Open Access
  This article is licensed under a Creative Commons Attribution 3.0 Unported Licence.
Sabrina Laís Alves Garcia, Gabriel Monteiro da Silva, Juliana Maria Svendsen Medeiros, Anna Paula Rocha de Queiroga, Blenda Brito de Queiroz, Daniely Rayane Bezerra de Farias, Joyceana Oliveira Correia, Eliane Rolim Florentino, Flávia Carolina Alonso Buriti
The content of this RSS Feed (c) The Royal Society of Chemistry




li

A chitosan-based edible film with clove essential oil and nisin for improving the quality and shelf life of pork patties in cold storage

RSC Adv., 2020, 10,17777-17786
DOI: 10.1039/D0RA02986F, Paper
Open Access
Karthikeyan Venkatachalam, Somwang Lekjing
This study assessed chitosan (CS)-based edible films with clove essential oil (CO) and nisin (NI) singly or in combination, for improving quality and shelf life of pork patties stored in cold conditions.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Ni stabilized rock-salt structured CoO; Co1−xNixO: tuning of eg electrons to develop a novel OER catalyst

RSC Adv., 2020, 10,17845-17853
DOI: 10.1039/D0RA03050C, Paper
Open Access
  This article is licensed under a Creative Commons Attribution 3.0 Unported Licence.
Rakesh Mondal, Himanshu Ratnawat, Sarvesh Kumar, Anil Kumar, Preetam Singh
Incorporation of Ni into CoO lattices helps to stabilize the rock salt structure and modulate the eg electrons to develop superior OER and ORR electrocatalysts.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Microwave roasting of blast furnace slag for carbon dioxide mineralization and energy analysis

RSC Adv., 2020, 10,17836-17844
DOI: 10.1039/D0RA02846K, Paper
Open Access
Zike Han, Jianqiu Gao, Xizhi Yuan, Yanjun Zhong, Xiaodong Ma, Zhiyuan Chen, Dongmei Luo, Ye Wang
This paper highlights the potential of microwave roasting in solid-waste treatment and carbon dioxide storage.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Enhanced methane gas storage in the form of hydrates: role of the confined water molecules in silica powders

RSC Adv., 2020, 10,17795-17804
DOI: 10.1039/D0RA01754J, Paper
Open Access
Pinnelli S. R. Prasad, Burla Sai Kiran, Kandadai Sowjanya
Rapid and efficient methane hydrate conversions by utilising the water molecules confined in intra- and inter-granular space of silica powders.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Synthesis, characterization and corrosion inhibition behavior of 2-aminofluorene bis-Schiff bases in circulating cooling water

RSC Adv., 2020, 10,17816-17828
DOI: 10.1039/D0RA01903H, Paper
Open Access
Wenchang Wei, Zheng Liu, Chuxin Liang, Guo-Cheng Han, Jiaxing Han, Shufen Zhang
Two new bis-Schiff bases, namely 2-bromoisophthalaldehyde-2-aminofluorene (M1) and glutaraldehyde 2-aminofluorene (M2) were synthesized and were characterized, the potentiodynamic polarization curve confirmed that they were anode type inhibitors.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Facile synthesis of a direct Z-scheme BiOCl–phosphotungstic acid heterojunction for the improved photodegradation of tetracycline

RSC Adv., 2020, 10,17369-17376
DOI: 10.1039/D0RA02396E, Paper
Open Access
Haijuan Tong, Bingfang Shi, Shulin Zhao
A one-step hydrothermal approach for synthesizing BiOCl–phosphotungstic acid (BiOCl–HPW) heterojunctions is proposed. The prepared BiOCl–HPW heterojunction exhibited good stability and photocatalytic activity.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Correction: Narrowing band gap and enhanced visible-light absorption of metal-doped non-toxic CsSnCl3 metal halides for potential optoelectronic applications

RSC Adv., 2020, 10,17869-17869
DOI: 10.1039/D0RA90054K, Correction
Open Access
  This article is licensed under a Creative Commons Attribution 3.0 Unported Licence.
Jakiul Islam, A. K. M. Akther Hossain
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Effect of new carbonyl cyanide aromatic hydrazones on biofilm inhibition against methicillin resistant Staphylococcus aureus

RSC Adv., 2020, 10,17854-17861
DOI: 10.1039/D0RA03124K, Paper
Open Access
  This article is licensed under a Creative Commons Attribution 3.0 Unported Licence.
Xueer Lu, Ziwen Zhang, Yingying Xu, Jun Lu, Wenjian Tang, Jing Zhang
2e and 2j with strong p-NO2 and p-CF3 at phenyl ring had the lowest MICs against S. aureus and MRSA. 2e displayed unaided or synergistic efficacy against MRSA, especially combined with ofloxacin. EM revealed that 2e destroys biofilms and cell membranes.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Lithium metal deposition/dissolution under uniaxial pressure with high-rigidity layered polyethylene separator

RSC Adv., 2020, 10,17805-17815
DOI: 10.1039/D0RA02788J, Paper
Open Access
  This article is licensed under a Creative Commons Attribution 3.0 Unported Licence.
Shogo Kanamori, Mitsuhiro Matsumoto, Sou Taminato, Daisuke Mori, Yasuo Takeda, Hoe Jin Hah, Takashi Takeuchi, Nobuyuki Imanishi
The use of a high rigidity separator and application of an appropriate amount of pressure are effective approaches to control lithium metal growth and improve its cycle performance.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Selenium modulates cadmium-induced ultrastructural and metabolic changes in cucumber seedlings

RSC Adv., 2020, 10,17892-17905
DOI: 10.1039/D0RA02866E, Paper
Open Access
Hongyan Sun, Xiaoyun Wang, Huimin Li, Jiahui Bi, Jia Yu, Xianjun Liu, Huanxin Zhou, Zhijiang Rong
Intensive insight into the potential mechanisms of Se-induced Cd tolerance in cucumber seedlings is essential for further improvement of vegetable crop cultivation and breeding to obtain high yields and quality in Cd-contaminated soil.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Synthesis of heteroatom-containing pyrrolidine derivatives based on Ti(O-iPr)4 and EtMgBr-catalyzed carbocyclization of allylpropargyl amines with Et2Zn

RSC Adv., 2020, 10,17881-17891
DOI: 10.1039/D0RA02677H, Paper
Open Access
  This article is licensed under a Creative Commons Attribution 3.0 Unported Licence.
Rita N. Kadikova, Ilfir R. Ramazanov, Azat M. Gabdullin, Oleg S. Mozgovoj, Usein M. Dzhemilev
The Ti(O-iPr)4 and EtMgBr-catalyzed regio and stereoselective carbocyclization of N-allyl-substituted 2-alkynylamines with Et2Zn, followed by deuterolysis or hydrolysis, affords the corresponding methylenepyrrolidine derivatives in high yields.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Nanoporous materials with predicted zeolite topologies

RSC Adv., 2020, 10,17760-17767
DOI: 10.1039/D0RA01888K, Paper
Open Access
  This article is licensed under a Creative Commons Attribution 3.0 Unported Licence.
Vladislav A. Blatov, Olga A. Blatova, Frits Daeyaert, Michael W. Deem
Topological exploration of crystal structures demonstrates the presence of known zeolites, inorganics, and MOFs in a database of predicted materials.
The content of this RSS Feed (c) The Royal Society of Chemistry




li

Glossary format definition list

Bruce Lawson recently asked for ways to style a definition list in the common glossary format. This is one way to do it.

Bruce’s original post – css challenge – describes what he is after: a “glossary style” appearance with the term on the left and the definitions on the right. Some terms will have multiple definitions, definitions of varying length, and each new term should appear on a new line. A definition list is semantically correct for this kind of information, so there was to be no fiddling around with the HTML, and the browser requirements were for it to work in all modern browsers and IE 6+.

You can skip straight to the demo where some additional classes are included in the HTML in order to highlight each term-definition association.

The basic HTML

The basic HTML structure is a simple definition list and nothing more. There are some short, long, and multiple definitions for each term.

<h1>Styling definition lists</h1>
<dl>
  <dt>Cheese</dt>
  <dd>
    <p>Velit esse cillum dolore in reprehenderit in voluptate duis aute irure dolor. Consectetur adipisicing elit, excepteur sint occaecat sunt in culpa. Velit esse cillum dolore eu fugiat nulla pariatur. Ut aliquip ex ea commodo consequat.</p>
    <p>Mollit anim id est laborum. Ut enim ad minim veniam, consectetur adipisicing elit, ullamco laboris nisi. Lorem ipsum dolor sit amet, sunt in culpa quis nostrud exercitation.</p>
  </dd>
  <dd>yummy!</dd>

  <dt>Building flexibility through spreading knowledge and self-organization, exploiting the productive lifecycle to experience a profound paradigm shift. Through the adoption of a proactive stance, the astute manager can adopt a position at the vanguard.</dt>
  <dd>balderdash</dd>;
  <dd>poppycock</dd>

  <dt>Aardvark</dt>
  <dd>never hurt anyone</dd>
</dl>

The styles

In order to get the required appearance in all browsers I had to use negative margins and a few conditional styles to get IE7 and IE6 to play along.

For the purposes of the demo I’ve placed all the styles in <style> blocks in the head of the document.

<style>
   dl {padding-left:300px;}
   dt {clear:both; float:left; width:260px; padding:10px; margin:0 0 2em -300px; font-weight:bold; color:#686663;}
   dd {float:left; width:100%; padding:10px 0; margin:0 0 2em;}
</styl>
<!--[if lte IE 7]>
<style>
   dt {display:inline; margin-bottom:0;}
   dd {float:none; width:auto;}
</style>
<![endif]-->

That’s it. The widths of the <dt> can be set in ems or percentages if the layout requires. The complete code is available in the demo and you are free to use this code.




li

Jump links and viewport positioning

Using within-page links presses the jumped-to content right at the very top of the viewport. This can be a problem when using a fixed header. With a bit of hackery, there are some CSS methods to insert space between the top of the viewport and the target element within a page.

Demo: Jump links and viewport positioning

Known support: varies depending on method used.

This experiment is the result of a post Chris Coyier made on Forrst. Chris’ method was to add an empty span element to the target element, shift the id attribute onto the span, and then absolutely position the span somewhere above it’s parent element.

That method works but it requires changes to the HTML. The comments on Chris’ post suggested the use of psuedo-elements or padding. This experiment expands on, and combines, some of those suggestions to show the limitations of each method and document their browser support.

Simplest method

If you need to jump to an element with simple styling then using the :before pseudo-element is a quick and simple approach.

#target:before {
   content: "";
   display: block;
   height: 50px;
   margin: -30px 0 0;
}

The drawbacks are that it requires browser support for pseudo-elements and it will fail if the target element has a background colour, a repeated background image, padding-top, or border-top as part of its rule set.

More robust method

The more robust method uses a transparent border, negative margin, and the background-clip property. If a top border is required then it can be mimicked using a pseudo-element, as described in Multiple Backgrounds and Borders with CSS 2.1.

#target {
   position: relative;
   border-top: 52px solid transparent;
   margin: -30px 0 0;
   -webkit-background-clip: padding-box;
   -moz-background-clip: padding;
   background-clip: padding-box;
}

#target:before {
   content: "";
   position: absolute;
   top: -2px;
   left: 0;
   right: 0;
   border-top: 2px solid #ccc;
}

There are still drawbacks: it requires browser support for background-clip if there is a background color, gradient, or repeating image set on the target element; it requires browser support for pseudo-elements and their positioning if a top border is desired; and it interferes with the standard use of margins.

To see these methods in action – as well as more details on the code, browser support, and drawbacks – have a look at the demo page. Please let me know if you know of better techniques.




li

About normalize.css

Normalize.css is a small CSS file that provides better cross-browser consistency in the default styling of HTML elements. It’s a modern, HTML5-ready, alternative to the traditional CSS reset.

Normalize.css is currently used in some form by Twitter Bootstrap, HTML5 Boilerplate, GOV.UK, Rdio, CSS Tricks, and many other frameworks, toolkits, and sites.

Overview

Normalize.css is an alternative to CSS resets. The project is the product of 100’s of hours of extensive research by @necolas and @jon_neal on the differences between default browser styles.

The aims of normalize.css are as follows:

  • Preserve useful browser defaults rather than erasing them.
  • Normalize styles for a wide range of HTML elements.
  • Correct bugs and common browser inconsistencies.
  • Improve usability with subtle improvements.
  • Explain the code using comments and detailed documentation.

It supports a wide range of browsers (including mobile browsers) and includes CSS that normalizes HTML5 elements, typography, lists, embedded content, forms, and tables.

Despite the project being based on the principle of normalization, it uses pragmatic defaults where they are preferable.

Normalize vs Reset

It’s worth understanding in greater detail how normalize.css differs from traditional CSS resets.

Normalize.css preserves useful defaults

Resets impose a homogenous visual style by flattening the default styles for almost all elements. In contrast, normalize.css retains many useful default browser styles. This means that you don’t have to redeclare styles for all the common typographic elements.

When an element has different default styles in different browsers, normalize.css aims to make those styles consistent and in line with modern standards when possible.

Normalize.css corrects common bugs

It fixes common desktop and mobile browser bugs that are out of scope for resets. This includes display settings for HTML5 elements, correcting font-size for preformatted text, SVG overflow in IE9, and many form-related bugs across browsers and operating systems.

For example, this is how normalize.css makes the new HTML5 search input type cross-browser consistent and stylable:

/**
 * 1. Addresses appearance set to searchfield in S5, Chrome
 * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
 */

input[type="search"] {
  -webkit-appearance: textfield; /* 1 */
  -moz-box-sizing: content-box;
  -webkit-box-sizing: content-box; /* 2 */
  box-sizing: content-box;
}

/**
 * Removes inner padding and search cancel button in S5, Chrome on OS X
 */

input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
}

Resets often fail to bring browsers to a level starting point with regards to how an element is rendered. This is particularly true of forms – an area where normalize.css can provide some significant assistance.

Normalize.css doesn’t clutter your debugging tools

A common irritation when using resets is the large inheritance chain that is displayed in browser CSS debugging tools.

A common sight in browser debugging tools when using a CSS reset

This is not such an issue with normalize.css because of the targeted styles and the conservative use of multiple selectors in rulesets.

Normalize.css is modular

The project is broken down into relatively independent sections, making it easy for you to see exactly which elements need specific styles. Furthermore, it gives you the potential to remove sections (e.g., the form normalizations) if you know they will never be needed by your website.

Normalize.css has extensive documentation

The normalize.css code is based on detailed cross-browser research and methodical testing. The file is heavily documented inline and further expanded upon in the GitHub Wiki. This means that you can find out what each line of code is doing, why it was included, what the differences are between browsers, and more easily run your own tests.

The project aims to help educate people on how browsers render elements by default, and make it easier for them to be involved in submitting improvements.

How to use normalize.css

First, install or download normalize.css from GitHub. There are then 2 main ways to make use of it.

Approach 1: use normalize.css as a starting point for your own project’s base CSS, customising the values to match the design’s requirements.

Approach 2: include normalize.css untouched and build upon it, overriding the defaults later in your CSS if necessary.

Closing comments

Normalize.css is significantly different in scope and execution to CSS resets. It’s worth trying it out to see if it fits with your development approach and preferences.

The project is developed in the open on GitHub. Anyone can report issues and submit patches. The full history of the project is available for anyone to see, and the context and reasoning for all changes can be found in the commit messages and the issue threads.

Detailed information on default UA styles: WHATWG suggestions for rendering HTML documents, Internet Explorer User Agent Style Sheets,and CSS2.1 User Agent Style Sheet Defaults.

Translations




li

Using canvas to fix SVG scaling in Internet Explorer

Internet Explorer 9–11 suffer from various bugs that prevent proper scaling of inline SVG’s. This is particularly problematic for SVG icons with variable widths. This is the canvas-based hack I’ve been using to work around the issue.

A popular way to use SVG icons is to generate a spritemap of SVG symbol‘s that you then reference from elsewhere in a document. Most articles on the topic assume your icon dimensions are uniformly square. Twitter’s SVG icons (crafted by @sofo) are variable width, to produce consistent horizontal whitespace around the vectors.

Most browsers will preserve the intrinsic aspect ratio of an SVG. Ideally, I want to set a common height for all the icons (e.g., 1em), and let the browser scale the width of each icon proportionally. This also makes it easy to resize icons in particular contexts – just change the height.

Unfortunately, IE 9–11 do not preserve the intrinsic aspect ratio of an inline SVG. The svg element will default to a width of 300px (the default for replaced content elements). This means it’s not easy to work with variable-width SVG icons. No amount of CSS hacking fixed the problem, so I looked elsewhere – and ended up using canvas.

canvas and aspect ratios

A canvas element – with height and width attributes set – will preserve its aspect ratio when one dimension is scaled. The example below sets a 3:1 aspect ratio.

<canvas height="1" width="3"></canvas>

You can then scale the canvas by changing either dimension in CSS.

canvas {
  display: block;
  height: 2rem;
}

Demo: proportional scaling of canvas.

Fixing SVG scaling in IE

This makes canvas useful for creating aspect ratios. Since IE doesn’t preserve the intrinsic aspect ratio of SVG icons, you can use canvas as a shim. A canvas of the correct aspect ratio provides a scalable frame. The svg can then be positioned to fill the space created by this frame.

The HTML is straightforward:

<div class="Icon" role="img" aria-label="Twitter">
  <canvas class="Icon-canvas" height="1" width="3"></canvas>
  <svg class="Icon-svg">
    <use fill="currentcolor" xlink:href="#icon-twitter"></use>
  </svg>
</div>

So is the CSS:

.Icon {
  display: inline-block;
  height: 1em; /* default icon height */
  position: relative;
  user-select: none;
}

.Icon-canvas {
  display: block;
  height: 100%;
  visibility: hidden;
}

.Icon-svg {
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%;
}

Setting the canvas height to 100% means it will scale based on the height of the component’s root element – just as SVG’s do in non-IE browsers. Changing the height of the Icon element scales the inner SVG icon while preserving its 3:1 aspect ratio.

Demo: proportional scaling of svg in IE.

Creating an Icon component

The hack is best added to (and eventually removed from) an existing icon component’s implementation.

If you’re generating and inlining an SVG spritemap, you will need to extract the height and width (usually from viewBox) of each of your icons during the build step. If you’re already using the gulp-svgstore plugin, it supports extracting metadata.

Those dimensions need to be set on the canvas element to produce the correct aspect ratio for a given icon.

Example React component (built with webpack):

import iconData from './lib/icons-data.json';
import React from 'react';
import './index.css';

class Icon extends React.Component {
  render() {
    const props = this.props;
    const height = iconData[props.name.height];
    const width = iconData[props.name.width];

    // React doesn't support namespaced attributes, so we have to set the
    // 'use' tag with innerHTML
    const useTag = `<use fill="currentcolor"
                      xlink:href="#icon-${props.name}">
                    </use>`;

    return (
      <span className="Icon">
        <canvas className="Icon-canvas"
          height={height}
          width={width}
        />
        <svg className="Icon-svg"
          dangerouslySetInnerHTML={{__html: useTag}}
          key={props.name}
        />
      </span>
    );
  }
}

export default Icon;

When I introduced this hack to a code base at Twitter, it had no impact on the the rest of the team or the rest of the code base – one of the many benefits of a component-based UI.




li

Redux modules and code-splitting

Twitter Lite uses Redux for state management and relies on code-splitting. However, Redux’s default API is not designed for applications that are incrementally-loaded during a user session.

This post describes how I added support for incrementally loading the Redux modules in Twitter Lite. It’s relatively straight-forward and proven in production over several years.

Redux modules

Redux modules comprise of a reducer, actions, action creators, and selectors. Organizing redux code into self-contained modules makes it possible to create APIs that don’t involve directly referencing the internal state of a reducer – this makes refactoring and testing a lot easier. (More about the concept of redux modules.)

Here’s an example of a small “redux module”.

// data/notifications/index.js

const initialState = [];
let notificationId = 0;

const createActionName = name => `app/notifications/${name}`;

// reducer
export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    case ADD_NOTIFICATION:
      return [...state, { ...action.payload, id: notificationId += 1 }];
    case REMOVE_NOTIFICATION:
      return state.slice(1);
    default:
      return state;
  }
}

// selectors
export const selectAllNotifications = state => state.notifications;
export const selectNextNotification = state => state.notifications[0];

// actions
export const ADD_NOTIFICATION = createActionName(ADD_NOTIFICATION);
export const REMOVE_NOTIFICATION = createActionName(REMOVE_NOTIFICATION);

// action creators
export const addNotification = payload => ({ payload, type: ADD_NOTIFICATION });
export const removeNotification = () => ({ type: REMOVE_NOTIFICATION });

This module can be used to add and select notifications. Here’s an example of how it can be used to provide props to a React component.

// components/NotificationView/connect.js

import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import { removeNotification, selectNextNotification } from '../../data/notifications';

const mapStateToProps = createStructuredSelector({
  nextNotification: selectNextNotification
});
const mapDispatchToProps = { removeNotification };

export default connect(mapStateToProps, mapDispatchToProps);
// components/NotificationView/index.js

import connect from './connect';
export class NotificationView extends React.Component { /*...*/ }
export default connect(NotificationView);

This allows you to import specific modules that are responsible for modifying and querying specific parts of the overall state. This can be very useful when relying on code-splitting.

However, problems with this approach are evident once it comes to adding the reducer to a Redux store.

// data/createStore.js

import { combineReducers, createStore } from 'redux';
Import notifications from './notifications';

const initialState = /* from local storage or server */

const reducer = combineReducers({ notifications });
const store = createStore(reducer, initialState);

export default store;

You’ll notice that the notifications namespace is defined at the time the store is created, and not by the Redux module that defines the reducer. If the “notifications” reducer name is changed in createStore, all the selectors in the “notifications” Redux module no longer work. Worse, every Redux module needs to be imported in the createStore file before it can be added to the store’s reducer. This doesn’t scale and isn’t good for large apps that rely on code-splitting to incrementally load modules. A large app could have dozens of Redux modules, many of which are only used by a few components and unnecessary for initial render.

Both of these issues can be avoided by introducing a Redux reducer registry.

Redux reducer registry

The reducer registry enables Redux reducers to be added to the store’s reducer after the store has been created. This allows Redux modules to be loaded on-demand, without requiring all Redux modules to be bundled in the main chunk for the store to correctly initialize.

// data/reducerRegistry.js

export class ReducerRegistry {
  constructor() {
    this._emitChange = null;
    this._reducers = {};
  }

  getReducers() {
    return { ...this._reducers };
  }

  register(name, reducer) {
    this._reducers = { ...this._reducers, [name]: reducer };
    if (this._emitChange) {
      this._emitChange(this.getReducers());
    }
  }

  setChangeListener(listener) {
    this._emitChange = listener;
  }
}

const reducerRegistry = new ReducerRegistry();
export default reducerRegistry;

Each Redux module can now register itself and define its own reducer name.

// data/notifications/index.js

import reducerRegistry from '../reducerRegistry';

const initialState = [];
let notificationId = 0;

const reducerName = 'notifications';

const createActionName = name => `app/${reducerName}/${name}`;

// reducer
export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    case ADD_NOTIFICATION:
      return [...state, { ...action.payload, id: notificationId += 1 }];
    case REMOVE_NOTIFICATION:
      return state.slice(1);
    default:
      return state;
  }
}

reducerRegistry.register(reducerName, reducer);

// selectors
export const selectAllNotifications = state => state[reducerName];
export const selectNextNotification = state => state[reducerName][0];

// actions
export const ADD_NOTIFICATION = createActionName(ADD_NOTIFICATION);
export const REMOVE_NOTIFICATION = createActionName(REMOVE_NOTIFICATION);

// action creators
export const addNotification = payload => ({ payload, type: ADD_NOTIFICATION });
export const removeNotification = () => ({ type: REMOVE_NOTIFICATION });

Next, we need to replace the store’s combined reducer whenever a new reducer is registered (e.g., after loading an on-demand chunk). This is complicated slightly by the need to preserve initial state that may have been created by reducers that aren’t yet loaded on the client. By default, once an action is dispatched, Redux will throw away state that is not tied to a known reducer. To avoid that, reducer stubs are created to preserve the state.

// data/createStore.js

import { combineReducers, createStore } from 'redux';
import reducerRegistry from './reducerRegistry';

const initialState = /* from local storage or server */

// Preserve initial state for not-yet-loaded reducers
const combine = (reducers) => {
  const reducerNames = Object.keys(reducers);
  Object.keys(initialState).forEach(item => {
    if (reducerNames.indexOf(item) === -1) {
      reducers[item] = (state = null) => state;
    }
  });
  return combineReducers(reducers);
};

const reducer = combine(reducerRegistry.getReducers());
const store = createStore(reducer, initialState);

// Replace the store's reducer whenever a new reducer is registered.
reducerRegistry.setChangeListener(reducers => {
  store.replaceReducer(combine(reducers));
});

export default store;

Managing the Redux store’s reducer with a registry should help you better code-split your application and modularize your state management.




li

Making SVG icon libraries for React apps

Using SVG is currently the best way to create icon libraries for apps. Icons built with SVG are scalable and adjustable, but also discrete, which allows them to be incrementally loaded and updated. In contrast, icons built as fonts cannot be incrementally loaded or updated. This alone makes SVG icons the better choice for high-performance apps that rely on code-splitting and incremental deploys.

This post describes how to make a package of React components from a library of SVG icons. Although I’m focusing on React, making any other type of package is also possible. At Twitter I used the approach described here to publish the company’s SVG icon library in several different formats: optimized SVGs, plain JavaScript modules, React DOM components, and React Native components.

Using the icons

The end result is a JavaScript package that can be installed and used like any other JavaScript package.

yarnpkg add @acme/react-icons

Each icon is available as an individually exported React component.

import IconCamera from '@acme/react-icons/camera';

This allows your module bundler to package only the icons that are needed, and icons can be efficiently split across chunks when using code-splitting. This is a significant advantage over icon libraries that require fonts and bundle all icons into a single component.

// entire icon library is bundled with your app
import Icon from '@acme/react-icons';
const IconCamera = <Icon name='camera' />;

Each icon is straightforward to customize (e.g., color and dimensions) on a per-use basis.

import IconCamera from '@twitter/react-icons/camera';
const Icon = (
  <IconCamera
    style={{ color: 'white', height: '2em' }}
  />
);

Although the icons render to SVG, this is an implementation detail that isn’t exposed to users of the components.

Creating components

Each React component renders an inline SVG, using path and dimensions data extracted from the SVG source files. A helper function called createIconComponent means that only a few lines of boilerplate are needed to create a component from SVG data.

import createIconComponent from './utils/createIconComponent';
import React from 'react';
const IconCamera = createIconComponent({
  content: <g><path d='...'></g>,
  height: 24,
  width: 24
});
IconCamera.displayName = 'IconCamera';
export default IconCamera;

This is an example of what the createIconComponent function looks like when building components for a web app like Twitter Lite, which is built with React Native for Web.

// createIconComponent.js
import { createElement, StyleSheet } from 'react-native-web';
import React from 'react';

const createIconComponent = ({ content, height, width }) =>
  (initialProps) => {
    const props = {
      ...initialProps,
      style: StyleSheet.compose(styles.root, initialProps.style),
      viewBox: `0 0 ${width} ${height}`
    };

    return createElement('svg', props, content);
  };

const styles = StyleSheet.create({
  root: {
    display: 'inline-block',
    fill: 'currentcolor',
    height: '1.25em',
    maxWidth: '100%',
    position: 'relative',
    userSelect: 'none',
    textAlignVertical: 'text-bottom'
  }
});

Setting the fill style to currentcolor allows you to control the color of the SVG using the color style property instead.

All that’s left is to use scripts to process the SVGs and generate each React component.

Creating icon packages

A complete example of one way to do this can be found in the icon-builder-example repository on GitHub.

The project structure of the example tool looks like this.

.
├── README.md
├── package.json
├── scripts/
    ├── build.js
    ├── createReactPackage.js
    └── svgOptimize.js
└── src/
    ├── alerts.svg
    ├── camera.svg
    ├── circle.svg
    └── ...

The build script uses SVGO to optimize the SVGs, extract SVG path data, and extract metadata. The example packager for React then uses templates to create a package.json and the React icon components shown earlier.

import createIconComponent from './utils/createIconComponent';
import React from 'react';
const ${componentName} = createIconComponent({
  height: ${height},
  width: ${width},
  content: <g>${paths}</g>
});
${componentName}.displayName = '${componentName}';
export default ${componentName};

Additional packagers can be included to build other package types from the same SVG source. When the underlying icon library changes, it only takes a couple of commands to rebuild hundreds of icons and publish new versions of each package.




li

Coronavirus | Lockdown chokes Maharashtra’s economic lifeline

The industrial hub faces a massive shortfall in revenues amid growing cost of combating the pandemic




li

Migrant workers | Maharashtra train accident victims were battling hunger

The previous night, they had called up relatives in Madhya Pradesh to say they were in a helpless state




li

Crime Branch busts cigarette, tobacco smuggling racket

Material brought illegally in vehicles that had permission to carry fruits and vegetables




li

Tablighi Jamaat: 10 Indonesian nationals granted bail

Mumbai civil and sessions court gives anticipatory bail to two others who are in quarantine




li

Punjab police arrest gangster Baljinder Singh

He is wanted for murder, attempt to murder and smuggling of weapons and drugs




li

Punjab Cabinet nod for non-teaching staff transfer policy

State mulling changes in excise policy, labour laws amid lockdown




li

Muslim villagers help Hindu woman's last rites




li

Illicit liquor racket busted




li

Populist measures in the time of lockdown




li

Strawberry cultivator’s hope blighted with frustration




li

Legislators named in delimitation panel




li

COVID19 claims second life




li

Guwahati likely to slip into orange zone




li

Stop complainers and energy drainers [electronic resource] : how to negotiate work drama to get more done / Linda Byars Swindling

Swindling, Linda Byars, 1965-




li

Strategic information management [electronic resource] : challenges and strategies in managing information systems / R.D. Galliers and D.E. Leidner

Galliers, Robert, 1947-




li

Strategien zur Vermeidung von Burnout [electronic resource] : der mögliche Einfluss von Coping-Stilen / Markus H. Kipfer

Kipfer, Markus H, author




li

Strategische personalentwicklung in der praxis [electronic resource] : instrumente, erfolgsmodelle, checklisten, praxisbeispiele. / Christine Wegerich

Wegerich, Christine, author




li

Strategisches management und marketing [electronic resource] : markt- und wettbewerbsanalyse, strategische frühaufklärung, portfolio-management / Edgar Kreilkamp

Kreilkamp, Edgar




li

The strategy of execution [electronic resource] : the five-step guide for turning vision into action / Liz Mellon and Simon Carter

Mellon, Elizabeth




li

Streamlining business requirements [electronic resource] : the XCellR8 approach / Gerrie Caudle

Caudle, Gerrie




li

Stress less. achieve more [electronic resource] : simple ways to turn pressure into a positive force in your life / Aimee Bernstein

Bernstein, Aimee




li

The stress test every business needs [electronic resource] : a capital agenda for confidently facing digital disruption, difficult investors, recessions and geopolitical threats / Jeffrey R. Greene, Steve Krouskos, Julie Hood, Harsha Basnayake, William Ca

Greene, Jeffrey R., author