How to efficiently style a table inline in react - css

I can style a table in react via:
var tableStyle = {
"border": "1px solid black"
};
return (
<div>
<h1>My Awesome Table</h1>
<table style={tableStyle}>
<th>Awesome Header</th>
Coupling my style and html into a reusable component is the react way of doing things. How can I effectively style my whole table? I could style each header via:
<th style={headerStyle}>
<th style={headerStyle}>
<th style={headerStyle}>
and
<tr style={rowStyle}>
<tr style={rowStyle}>
That's not very efficient. In plain old CSS I can just do
table {
//boom style all the things
}
th {
}
tr {
}
Using CSS, particularly in a SPA application can become a maintenance headache. So I like the idea of sticking my style into this component where nobody else will inherit it. How can I do it without writing a bunch of repetitive code?

Not entirely sure I understand what you're looking for, but you want a better way of having css and markup in one file with no external dependencies?
If so, this might work:
return (
<style>{`
table{
border:1px solid black;
}
`}</style>
<div>
<h1>My Awesome Table</h1>
<table>
<th>Awesome Header</th>
...
)
Using template literal string formatting seems necessary here to support the <style> contents to span across multiple lines.
Alternatively:
<style>{"table{border:1px solid black;}"}</style>

You should have all of your styles in a separate folder/ and file and maintain separation of concerns. No CSS declarations should be in your JavaScript. If must style your components, you should be using CSS classes instead of inline-styles.
Then you could style all of your tables from one CSS file.
/*CSS file*/
table.myAwesomeTable {
...code
}
/*Markup */
<table className="myAwesomeTable">
</table>

define style in your global theme.js
"table, th, td" :{
border: "1px solid white" },
"th, td" : {
textAlign: "center"
},
All tables in App will now display white border

Related

Styling a vanilla html table in react with a style-components

I have a regular HTML table in my app with the following structure (the values are not important):
<table>
<tr>
<th>Header Row 1</th>
<th>Header Row 2</th>
</tr>
{Object.values(someArray).map((value, index) => {
return (
<tr>
<td>{value.1}</td>
<td>{value.2}</td>
<td>{value.3}</td>
</tr>
);
})}
</table>
I'm trying to solve the problem of having my .css rules being globally applied, as I want different tables to have different styling rules.
So I started to implement styled-components.
This is what I came up with
const CustomTable = styled.table`
&&& {
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
th,
td,
tr {
padding: 5px;
}
th {
text-align: left;
}
table {
width: 100%;
}
}
`;
Only the first grouping of rules seems to be applied to my table. So padding, text-align, and width doesn't seem to take effect. Is this a valid structure (grouping multiple elements that have multiple rules) or do I need to individually create styled-components for each table element (<td>, <td>, .. etc)?
If you want to add global styles you can usecreateGlobalStyle from styled-components and use it to inject global styles to your components.
import { createGlobalStyle } from "styled-components"
like this, I have updated #deve's code.Codesandboxlink

Angular 5 does not generate some CSS rules from SCSS

I write an Angular 5 application, and I cannot get some CSS rules generated.
Here is a small example, HTML:
<table class="table-rule">
<tr>
<td class="cell-rule">demo text</td>
</tr>
</table>
SCSS:
.table-rule {
font-weight: bold;
.cell-rule {
color: red;
}
}
And here is the problem: I should get a bold red text in a table, but I get only red text (not bold). I found out that Angular generates such a CSS:
.table-rule .cell-rule { color: red }
It does not generate CSS rule for ".table-rule" selector. Only for ".table-rule .cell-rule" selector.
Any ideas why is it so and how can it be fixed?
P.S. pure HTML+CSS works fine: http://jsbin.com/maxagin/edit?html,css,output
Found a problem: in a production .scss file there was an empty comments line between two rules:
.rule1 {
...
}
/**/ <---- this one!
.rule1 {
...
}
Removing this comment (/**/) fixed SCSS to CSS conversion.
Strange bug in SCSS.

Angular reapply table striping after hiding rows

I've got a table that needs to be striped but it has some rows that may become hidden later on. After hiding some of the rows re-striping does not occur so the striping is off. How can I force the table to re-stripe itself? Here is my css that I feel should work, but it's not. And then also my html.
.isHidden {
display:none;
}
tbody {
tr:not(.isHidden):nth-child(odd) {
background: rgb(238, 238, 238);
}
}
<tbody>
<tr [ngClass]="{'isHidden': !line.get('isVisible').value}" *ngFor="let line of lineDetailsArray.controls; let i=index;">
...
</tr>
</tbody>
At present, you won't be able to solve the problem with CSS only, unfortunately. True, there's a potentially useful addition in the spec - :nth-child(An+B of S). The following example exactly matches your case:
Normally, to zebra-stripe a table’s rows, an author would use CSS
similar to the following:
tr {
background: white;
}
tr:nth-child(even) {
background: silver;
}
However, if some of the rows are hidden and not displayed, this
can break up the pattern, causing multiple adjacent rows to have the
same background color. Assuming that rows are hidden with the [hidden]
attribute in HTML, the following CSS would zebra-stripe the table rows
robustly, maintaining a proper alternating background regardless of
which rows are hidden:
tr {
background: white;
}
tr:nth-child(even of :not([hidden])) {
background: silver;
}
The caveat? Support of this option in browsers is not even limited: it's non-existent.
But still, there's a way out of this misery. Even though Angular won't just let you place ngIf and ngFor on a single element (it'll be way too simple I suppose), there's a workaround - using <ng-container> as a placeholder:
<ng-container *ngFor="let item of list">
<ng-container *ngIf="!item.hidden">
<tr>
<td>{{item.name}}</td>
<td><input type="checkbox"
[checked]="item.hidden"
(change)="item.hidden = !item.hidden" /></td>
</tr>
</ng-container>
</ng-container>
Demo (kudos to #imkremen for helping to create this one).

add CSS classes on ajax update?

I have a JSF app and I generate <table>s dynamically based on some data.
For each cell I dynamically generate the css class and I write all the classes in the *.jsf File (using ResponseWriter)
A simplified resulting page:
<div id="styles">
<style type="text/css">
cell1 {
color: red;
}
cell2 {
color: blue;
}
cell3 {
color: black;
}
cell4 {
color: green;
}
</style>
</div>
<table style="width:100%">
<tr>
<td class="cell1">Jill</td>
<td class="cell2">Smith</td>
</tr>
<tr>
<td class="cell3">Eve</td>
<td class="cell4">Jackson</td>
</tr>
</table>
The table can be very big and it is possible for cells to share the same style.
The cell styles can change based on some user input in the table. I can update the cell on ajax request overriding UIComponent.visitTree(VisitContext context, VisitCallback callback)
but I have no idea if and how I can add additional css classes.
I think I have found a solution: inside UIComponent.visitTree(VisitContext context, VisitCallback callback) I can rewrite the cell (<td>) and add the <style type="text/css"> tag as child of the <td> tag adding the new CSS classes to it.

Correct method of setting CSS font-weight?

I am constructing a basic html5 website with 5 pages for practice as I am in the process of relearning html5 and CSS.
I have a div with ID "education" and Class "content-list".
Inside this div is a Caption and an unordered list Class "content-ul"(NOTE: Caption is contained in "content-list"). The list contains 3 list items.
I want to set the font-weight to bold for the caption, but not the unordered list.
Here's what I have:
HTML:
HTML:
<div id="education" class="content-list">
<caption>Education:</caption>
<ul class="content-ul">
<li>Tafe</li>
<li>College</li>
<li>High School</li>
</ul>
</div>
CSS:
.content-list {
... styles
font-weight:bold; /* Sets caption and list to bold */
.... styles
}
.content-ul {
.... styles
font-weight:normal; /* Sets list back to normal */
.... styles
}
This achieves the desired result, but I am wondering if there is a better/more efficient way of doing this.
Keep in mind, 4 of the 5 pages use this code. For this reason I opted against using in line styles as I would have to do it 4 times in total. This would remove the need to set the list to bold and then back to normal again, but would still use more code than the chosen method.
Any help/suggestions would be great.
caption is for tables, use i.e. a h4 for lists
<div id="education" class="content-list">
<h4>Education:</h4>
<ul class="content-ul">
<li>Tafe</li>
<li>College</li>
<li>High School</li>
</ul>
</div>
Side note, styling a caption work when used properly
table, th, td {
border: 1px solid black;
}
table caption {
color: red;
font-weight: bold;
}
<table>
<caption>Caption</caption>
<tr>
<th>Header</th>
</tr>
<tr>
<td>Cell</td>
</tr>
</table>
Looking through your example, I can see you only want Education to be bold and not the content other than it. For this simply, do it like
caption{
font-weight:bold
}
CSS in OP won't be needed.

Resources