One of the styles doesn't work but the other do - javascript

I am making a web page to play a game. It uses two containers (inside a component). They show 2 images but by default they are empty. I apply one style to them: img-container which set the dimentions and color the background (it must be black), but the style doesn't work, although all other styles do.
Clarifications: At start, the div uses 2 classes (img-container and flex-child, which works fine). Also, I am working with Visual Studio Code.
I already try: change class name, reboot the host (closing VS Code an using 'npm start'), using another web browser (chrome and firefox) and change property values for bigger ones. This doesn't work but insert the properties in preexisting CSS classes and call they do.
Component code:
import React, { Component } from 'react';
//Class component
class PPT extends Component {
render() {
return (
<div id = "PPT">
<h3 id="explanation">¿Cómo se juega? </h3>
<div id="container" className="flex-parent">
<div id="player_hand" className="flex-child">
<h2>Jugador</h2>
<div className="img-container"></div>
</div>
<div id="computer_hand" className="flex-child">
<h2>Computadora</h2>
<div className="img-container"></div>
</div>
</div>
</div>
)
}
}
export default PPT;
CSS style:
#PPT {
margin-top: 90px;
margin-bottom: 15px;
}
#img-container {
background-color: #262626;
width: 474px;
height: 266px;
}

You are using #img-container while you must use .img-container because it's a class. I also suggest that you remove that hyphen(-) and use an _ instead to maintain proper naming convention of classes in react and to also respect lint rule as your approach will show a warning in some editors. At the end your class name must look like img_container in jsx and like this .img_conatiner in css.

The wrong part is this section in your JSX:
className="img-container"
since you are using className you have to provide a class in your related css file for it, like below:
.img-container {
background-color: #262626;
width: 474px;
height: 266px;
}
You are selecting your element in a wrong way!

In CSS, # is an ID selector, while . is a class selector. So, to target an element with class name img-container, you should use .image-container, and not #img-container.

Related

Accessing CSS style with Vue.js

I am trying to make website and I need to get access to my style thorough Vue.
I need to access CSS with Vue because style .skill-bar is background of bar and .skill-bar-fill is green filament which is supposed to have width based on number defined in Vue:
So I mean how can I change style of this .skill-bar-fill anytime I want by just changing number in Vue?
How can I change width of .skill-bar-fill separately in every item?
HTML
<div class="w-100 skill-bar">
<div class=" skill-bar-fill"> {{ programming.item1}} %</div>
</div>
CSS
.skill-bar{
text-align: center;
color: $black;
font-size: 0.75rem;
height: 1rem;
background: $bg-light;
border-radius: 1rem;
}
.skill-bar-fill{
height: 1rem;
background: $green;
border-radius: 1rem;
}
Vue
export default {
name: 'Items',
data() {
return{
programming: {item1: 95, item2: 90, },
}
}
}
And I am trying
Keep the class skill-bar-fill and use style binding :
<div class="w-100 skill-bar">
<div class=" skill-bar-fill" :style="{width:programming.item1+'%'}"> {{ programming.item1}} %</div>
</div>
You couldn't modify a property of that class since it's not unique and each item is unique.
This answer is based on original question. Your requirement has been simplified so your solution is fine and below is probably not required
For the first instance, you could use a CSS variable for the width attribute, and programatically change the variable. For subsequence instances, this won't work by itself because they share the CSS so for those you'd need an object style syntax.
Pass a property to the first child so it knows it's the first one and it needs to set the variable
Setting CSS variable in Vue:
Add var into css class
For subsequent children use object syntax:
https://v2.vuejs.org/v2/guide/class-and-style.html#Object-Syntax-1
It's not clear to me why you the width of divs needs to reference the first uncle - what if the second skill is higher than the first? - but the above might be the answer.

:host-context not working as expected in Lit-Element web component

I've got two Lit-element web components - one is units-list, which contains many units-list-item elements. The units-list-item elements have two different display modes: compact and detailed. Because the list element supports infinite scroll (and thus could contain several thousand units), we need any mechanism that toggles between the two modes to be as performant as possible.
That's why I thought an ideal solution would be to use the :host-context() pseudo-selector in the styles for the units-list-item element, as that way every units-list-item element could switch between the two display modes just by changing the class applied to an ancestor (which would be within the shadow DOM of the units-list element).
To elaborate, here's the relevant markup from the units-list element. Note that the "trigger" classes are being applied to the #list-contents div, which is part of the units-list template.
<div id="list-contents" class="${showDetails ? 'detail-view table' : 'compact-view table'}">
${units.map(unit => html`<units-list-item .unit="${unit}"></units-list-item>`)}
</div>
As you can see, the showDetails flag controls whether the "detail-view" or "compact-view" class is applied to the div containing all of the units-list-item elements. Those classes are definitely being applied correctly.
Here's the full render method from the units-list-item element (unnecessary markup removed):
render() {
const {unit} = this;
// the style token below injects the processed stylesheet contents into the template
return html`
${style}
<div class="row compact">
<!-- compact row markup here -->
</div>
<div class="row detail">
<!-- detail row markup here -->
</div>
`;
}
Then I have the following in the units-list-item element's styles (we're using SCSS, so the single-line comments are not a problem):
// This SHOULD hide the compact version of the row when the
// unit list has a "detail" class applied
:host-context(.detail-view) div.row.compact {
display: none !important;
}
// This SHOULD hide the detail version of the row when the
// unit list has a "compact" class applied
:host-context(.compact-view) div.row.detail {
display: none !important;
}
My understanding of the :host-context selector says that this should work, but Chrome just renders both versions of the row every time, and the Chrome dev tools show that the selectors are never matching with either of the rows.
I know there are several alternatives that would work, but this is the only one I'm aware of that would allow the entire list of units to switch modes by changing a single class on a parent element. Every other solution I've considered would require, at the least, updating the class attribute on every units-list-item element in the list. I'd like to avoid that if possible.
Of course, my primary concern is simply to make this work, if possible, but I'm also curious about a couple of things and can't find any info about them. The two questions I can't seem to find an answer for are
When :host-context is used within an element that is itself part of a shadow DOM, does it consider that parent element's shadow DOM to be the "host context", or does it jump "all the way out" to the document DOM?
If it's the former, will :host-context jump multiple shadow DOM boundaries? Say I have a custom page element that contains a custom list element, which itself contains many custom item elements. If that item element has a :host-context rule, will the browser first scan up the shadow DOM of the list element, then, if matching nothing, scan up the shadow DOM of the page element, and if still matching nothing, then scan up the main document DOM to the <html> tag?
There is no support for :host-context in FireFox or Safari
last update from a month ago is both Mozilla and Apple are not going to implement it.
Looks like it is going to be removed from the spec:
https://github.com/w3c/csswg-drafts/issues/1914
One alternative is to use CSS Properties (those trickle down into
shadowDOM)
JSFiddle: https://jsfiddle.net/WebComponents/hpd6yvxt/
using host-context for Chrome and Edge
using CSS properties for other Browsers
Update Feb 2022
Apple quietly changed their mind? now in Safari TP:
https://caniuse.com/?search=host-context
An example of using css porperties, as Danny Engelman says, to get your goal
customElements.define('list-item', class extends HTMLElement {
constructor() {
const style = document.createElement('style');
const divcompact = document.createElement('div');
divcompact.innerHTML = "compact";
divcompact.className = "compact";
const divdetail = document.createElement('div');
divdetail.innerHTML = "detail";
divdetail.className = "detail";
let shadow = super().attachShadow({
mode: 'open'
});
shadow.append(style, divcompact, divdetail);
style.innerHTML = `
.compact {
background-color: red;
display: var(--display-compact, block);
}
.detail {
background-color: green;
display: var(--display-detail, block);
}
`
}
});
.compact-view {
--display-detail: none;
}
.detail-view {
--display-compact: none;
}
.box {
width: 200px;
height: 50px;
border: solid 1px black;
margin: 5px;
}
<div class="box">
no class applied
<list-item>test</list-item>
</div>
<div class="compact-view box">
compact view
<list-item>test</list-item>
</div>
<div class="detail-view box">
detail view
<list-item>test</list-item>
</div>

ReactJS styles 'leaking' to other components

So I have two components... a Navbar component, and an AboutPage component.
They are both in the same directory, 'App'
App
-- Navbar --> Navbar.css, Navbar.js
-- AboutPage --> Aboutpage.css, Aboutpage.js
So as you can see, they have two separate stylesheets.
In the JS pages the correct CSS file is being imported as well.
When I do a style like this for example:
Navbar Component
p { background: red }
^^ this style also applies to the p's in the Aboutpage. I even tried to give the P in Aboutpage its on id and style it that way and it still failed.
That's the expected behaviour.
No matter which file you specify a rule like p { background: red }, it's going to be applied to all DOM.
Specifying and id attribute to won't work either. The above rule is general enough to apply to all <p>s.
If you want to specify css files for each component, you should also create component specific css classes. Like the following example.
import React from 'react';
import './DottedBox.css';
const DottedBox = () => (
<div className="DottedBox">
<p className="DottedBox_content">Get started with CSS styling</p>
</div>
);
export default DottedBox;
and its css file:
.DottedBox {
margin: 40px;
border: 5px dotted pink;
}
.DottedBox_content {
font-size: 15px;
text-align: center;
}
If you want different ways of defining css for React, this resource adds 3 more ways of doing so, in addition to the above way.
You can also use css modules. They scope your CSS locally and are awesome
Scoping styles to a component requires WebComponents which relies on several newer browser features, particularly shadowRoot "shadownDOM" which supports this separation directly. These are most easily used with lit-element and/or Polymer 3.
Sometimes we need a global CSS which could affect another component even if we use module import, I didn't find anything to answer that in the official documentation, so my workaround is to use something like the following code in the component itself, and, it works fine :)
<style>
{
`
#page {
padding:0;
margin-top:0;
margin-bottom: 0;
margin-left: 0;
margin-right:0;
}
#media print {
#page {
size: 80mm 21cm;
}
}
`
}
</style>

How to customize Ant.design styles

Who knows how to customize Ant.design styles in proper way?
For example, I want to change the default backgroundColor and height of Header section:
import React, { Component } from 'react';
import { Form, Layout } from 'antd';
const { Header, Footer, Sider, Content } = Layout;
export default class Login extends Component {
render () {
return (
<div>
<Layout>
<Header style={{backgroundColor: '#555555', height: '5vh'}}>header</Header>
<Layout>
<Content>main content</Content>
</Layout>
<Footer>footer</Footer>
</Layout>
</div>
)
}
}
Is it ok, or there is a better way to customize styles?
Because I have not found some component's attributes or smth. like this.
Antd has externized most of their styling variable in LESS variables
as you can see in
https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less
To be able to overwrite those variables you need to use modifyVar function from LESS
you can find more about theming here
So to your specific question, #layout-header-background does the job
This is how i customized the default antd styles in a particular component
In scss or less
.booking_information_table {
:global {
.ant-table-thead > tr > th,
.ant-table-tbody > tr > td {
padding: 0 0 !important;
background-color: unset;
border: none;
overflow-wrap: break-word;
}
}
}
In js file
after the import statement
import styles from './component.module.less'
In return
<Table
dataSource={bookingInformationDataSource}
columns={bookingInformationColumns}
pagination={false}
className={styles.booking_information_table}
/>
My personal approach (I'm working with dva-cli though):
Every time I need to override the CSS, I use a CSS file located in the same folder and import it such as:
your-component.js:
import styles from './your-stylesheet.css';
...
< AntdComponent className= {styles.thestyle} />
your-stylesheet.css:
.thestyle {
background-color: '#555555';
}
In the less file(like a CSS) you can handle customize styles. For
example in your case
.ant-layout-header{
height: 100vh;
background-color:#f50;
}
If you use Ant card
.ant-card-head{color:#j14}
I hope you can understand now
The above mentioned approaches work for simple components like Header but don't always work for complex components like Menu, Tabs, Collapse, Select, and others, due to styles nesting priority. At work we use the approach described by jayanes but we go deeper into nested Ant Design classes. Let me explain it in the following example: when you import Tabs from "antd", you have only 2 tags to override styles for: Tabs and TabPane.
<div className={styles.tabsContainer}>
<Tabs className={styles.tabs}>
<TabPane className={styles.tabPane}>
Tab 1 Title
</TabPane>
</Tabs>
</div>
But this antd component has a very complex structure. You can verify in dev tools: it has .ant-tabs-bar, .ant-tabs-nav-container, .ant-tabs-tab-prev, .ant-tabs-tab-next, .ant-tabs-nav-wrap, .ant-tabs-nav-scroll, .ant-tabs-tab-active, .ant-tabs-ink-bar and others.
The way to go is: in your less file nest the .ant-... classes inside your own parent component's className (in order to avoid overriding all the antd classes in the whole app after code compilation). Write there your own css properties, for example:
.tabsContainer {
.ant-tabs-tab-active {
background: #fff266;
color: #31365c;
&:hover {
color: darken(#31365c, 5%);
}
}
.ant-tabs-ink-bar {
background: #fff266;
}
}
If you still need more detailed explanation, please refer to the video I posted on YouTube on how to customize Ant Design components - tabs.
Override the component style
Because of the special needs of the project, we often meet the need to cover the component style, here is a simple example.
Override the component style
Customizing Antd theme Colors can be a hassle thus, I created a package that allows you to change them easily with post CSS you can even change them to CSS variables and change them in runtime.
For more info https://www.npmjs.com/package/ant-post-css-theme

conflict between the same class or id of multiple css files

Is there any way to stop the conflict between same class or id of multiple css files. As I am explaining below for better understanding:
There is a master web page which has several <div> but there is a <div class"dynamic"> which always reload the contents including css files. Let's suppose if any class of master page has the same name to reloaded elements' class while properties are different. Then how should I handle this to stop the conflict.
master.html
<html>
<head> //attached master.css file here </head>
<body>
<div class="myClass"> </div>
<div class="dynamic"> /* often reload elements by ajax */ </div>
</body>
</html>
master.css
.myClass { height: 100px; width: 150px; background : red;}
.dynamic { height: 200p; width: 200px; }
now i am showing the reloaded html elements & css files into dynamic div of master page
reloaded tag line by ajax : <div class"myClass"> </div>
reload.css
.myClass{height: 30px; width: 25px; background: yellow; }
Now as you can see there are two classes with same name but different properties. Then how should I stop the confliction?
#Edit Thanks everyone for your support & time but my problem is different here.
the dynamic reloaded contents & css files are streaming from the client/user machine while master html page & it's css streaing directly from server.
so whatever the contents loads in dynamic div, it's coming from client side (e.g. tag lines & css, js). in that case i am not able to handle the css file which is just reloaded by ajax() so i think it can be sort out using js/jQuery fn().
You could apply the cascading rules of the CSS:
In your case, div.myClass inside div.dynamic should override div.myClass belongs to the body.
you adjust the reload.css rules to
.dynamic .myClass{height: 30px; width: 25px; background: yellow; }
The cascading rules which are applied when determine which rules should apply to html div could be referenced here
Updated 11.23
As the OP only have control over master.css, the above solution won't work. Thus, I suggest use child selector to limit the CSS rules to only the outer div.myClass. Modify the rule in your master.css to:
body > .myClass {...}
This rule will only apply to the .myClass which is the child of body. It leaves the spaces of styling for inner .myClass div.
Option 1: A more specific selector
.dynamic .myClass { }
This selector selects the .myClass element that is a descendent of .dynamic.
.dynamic > .myClass { }
This selector selects the .myClass element that is a direct child of .dynamic.
Option 2: Inline CSS
<div class="dynamic">
<div class="myClass" style="background-color: yellow;"></div>
</div>
Option 3: Use a different class.
UPDATE
If you want to avoid the previous defined property to be overwritten by a later defined value, you can use the !important syntax.
.myClass { background-color: red !important; } /* Sets the property to red */
.myClass { background-color: yellow; } /* Property is NOT overwritten */
If I understand your question correctly, this should sort it.
So you should add !important to the properties that seem to be overwritten.
div.myclass { ble ble }
div.main div.myclass { ble ble }
<body>
<div class="myclass"></div>
<div class="main><div class="myclass"></div></div>
</body>
Whichever css class of the same name is loaded last will overwrite anything set by the earlier class. However, if you use an inline style attribute this will always take precedence over anything set by the css file (so using an inline style is one option).
You could also use different style names or clarify your style with tag names div.myClass or id's #myDiv.myClass.

Categories

Resources