How do I reference an inner class? - css

I'm using Material UI styling. it's my first time using that platform and it will be my last time. but for now, I'm stuck with it. so I have a question. I have something like:
.map(section => (
<Section className={classNames(classes.section, section.class)}>
<div className={classes.content}>
...
</div>
</Section>
))
where section names generally look like Section1, etc. I then want to style so I'm trying this:
{
section: {},
Section1: {
backgroundColor: 'black',
'& img': { ... }
content: { border: '1px solid pink' }
}
}
but the pink border is not getting applied and I can't figure out why
it appears the images get styled as expected, I see this in the generated code:
.makeStyles-Section1-415 {
content: [object Object];
}
.makeStyles-Section1-415 img {
margin-left: 400px;
}
from which it's obvious that the MUI class generator doesn't know how to produce the inner class name. obviously '& .content' wouldn't work either as the actual class name generated will look something like makeStyles-content-415
so what is the correct incantation to make this work?
p.s.
obviously I can do something heinous like:
{
Section1Content: {}
}
but if that's the correct answer it's a powerful reason to rip this styling system out completely

the answer is:
Section1: {
'& $content': { border: '1px solid pink' }

Related

Is there an `and` operator (&&) in Scss?

I have this HTML element:
<button class="Button Button--is-primary Button--is-disabled Button--is-dark-theme">
And I need to defined in Scss a set of deep selectors like this:
.Button {
// Apply this for all Buttons that are dark theme
&--is-dark-theme {
// Apply this for all Buttons that are Dark AND are Primary
&--is-primary {
//...
}
}
}
But, my problem is that rule is going to create this:
.Button--is-dark-theme--is-primary
When I actually need:
.Button--is-dark-theme.Button--is-primary
I just found this:
.Button {
$self: &;
// Apply this for all Buttons that are dark theme
&--is-dark-theme {
// Apply this for all Buttons that are Dark AND are Primary
&#{$self}--is-primary {
color: red;
}
}
}
Which generates:
.Button--is-dark-theme.Button--is-primary {
color: red;
}
Any better option?

Video.js change Focus style

I'm using Video.js together with Vue.js and Electron.js and I'm trying to change the outline of the video player to something a bit better looking than the standard yellow outline but the outline just stays as it is.
My Video Component:
<template>
<div id="video-container">
<video class="video-js" id="video-player" ref="video"></video>
</div>
</template>
<script>
import videojs from "video.js";
export default {
name: "Preferences",
props: ["item"],
methods: {
getPath: function () {
return this.item.dir + "/" + this.item.name + "." + this.item.fileType;
},
},
mounted: function () {
let options = {
autoplay: false,
controls: true,
fluid: true,
playbackRates: [0.5, 1, 1.25, 1.5, 1.75, 2],
controlBar: {
pictureInPictureToggle: false,
},
};
this.player = videojs(this.$refs.video, options).src(this.getPath());
},
};
</script>
<style scoped>
#video-player {
outline: none;
}
</style>
I've also tried !important, #video-player:hover and using the video-container div to change the outline but so far nothing worked.
The outline looks like this:
Video Box outline
button outline
If I understand what you are saying, you are talking about the bowser focus, that blue line around the focus component.
you need something like
.video-js:focus {
outline-style: none;
}
if still not working you can add !important or add this too
.video-js:focus {
outline-style: none;
box-shadow: none;
border-color: transparent;
}
Normally we don't remove this for the simple reason that could be hard to use Tab around the components. But if you are ok with that go for it!
EDIT (10/02/2021):
So for the video JS, you can actually use your custom class and overwrite the Video-js CSS class in order to do that you will need to create this 3 follow classes in your CSS.
.vjs-matrix.video-js {
color: #00ff00;
/*put other stuff you need here*/
}
/* Change the border of the big play button. */
.vjs-matrix .vjs-big-play-button {
border-color: #00ff00;
/*put other stuff you need here*/
}
/* Change the color of various "bars". */
.vjs-matrix .vjs-volume-level,
.vjs-matrix .vjs-play-progress,
.vjs-matrix .vjs-slider-bar {
background: #00ff00;
/*put other stuff you need here*/
}
And for your HTML
<video class="vjs-matrix video-js">...</video>
Try to play around with this and see if fix your problem!
Source (videojs)

CSS Modules - exclude class from being transformed

I'm using CSS modules and by far everything was working great.
We started to use external UI library along with our own one, so I'm writing components like this:
<div className={styles['my-component']}>
<ExternalUIComponent />
</div>
Assuming that the ExternalUIComponent has its own class that in the final CSS file looks like this external-ui-component, how can I make adjust this component styling from my css file? The below example does not work:
.my-component {
font-size: 1em;
}
.my-component .external-ui-component {
padding: 16px;
// Some other styling adjustments here
}
Please do not use inline styles as someone else suggested. Stay away from inline styles as much as you can because they can cause unnecessary re-renders.
You should use global instead.
.my-component {
:global {
.external-ui-component {
padding: 16px;
// Some other styling adjustments here
}
}
}
https://github.com/css-modules/css-modules#usage-with-preprocessors
Also, I recommend using camel case style names which is the preferred way for css-modules.
So your class name would be : .myComponent { ... }
And you can use it in your code as
<div className={ styles.myComponent } >
If you wanted to add more styles , you can use the array.join(' ') syntax.
<div className={ [ styles.myComponent, styles.anotherStyle ].join(' ') } >
This is cleaner!
Here's a shorter form in pure CSS (i.e. no preprocessor needed):
.my-component :global .external-ui-component {
// ...
}
Did you try inline styles for that component ?
https://reactjs.org/docs/dom-elements.html#style
const divStyle = {
color: 'blue',
backgroundImage: 'url(' + imgUrl + ')',
};
function HelloWorldComponent() {
return <div style={divStyle}>Hello World!</div>;
}

How to change the style of a Ant-Design 'Select' component?

Suppose I want to change the standard white background color of the Select component to green.
My try...
<Select
style={{ backgroundColor: 'green' }}>
// Options...
</Select>
...didn't do it.
Can someone point me in the right direction?
[EDIT]
I ended up using the suggested approach from Jesper We.
Overwriting the color for all selections...
.ant-select-selection {
background-color: transparent;
}
...then I could style the Select components individually.
<Select> renders a whole set of <div>s, you need to take a look at the resulting HTML element tree to understand what you are doing. You can't do it through the style attribute, you need to do it in CSS.
The proper place to attach a background color is
.ant-select-selection {
background-color: green;
}
This will make all your selects green. Give them individual classNames if you want different colors for different selects.
For my form with Select element a have some code in render:
const stateTasksOptions =
this.tasksStore.filters.init.state.map(item =>
<Select.Option key={item.id} value={item.id} title={<span className={`${item.id}Label`}>{item.title}</span>}>
<span className={`${item.id}Label`}>{item.title}</span> - <span class="normal-text">{item.help}</span>
</Select.Option>
)
return (
....
<Select
mode="multiple"
value={this.tasksStore.filters.selected.state.map(d => d)}
onChange={this.handleTasksStatus}
optionLabelProp="title"
>
{stateTasksOptions}
</Select>
....
)
And some css for colorizing.
Result:
Try dropdownStyle instead of style.
<Select
dropdownStyle={{ backgroundColor: 'green' }}>
// Options...
</Select>
dropdownStyle is one of select props.
reference: antd select
From their official docs https://pro.ant.design/docs/style
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.
Antd Select In multi-select state, the default will show all the select items, here we add a limit height for display scroll bar when the content beyond this height.
// TestPage.ts
import { Select } from 'antd';
import styles from './TestPage.less';
const Option = Select.Option;
const children = [];
for (let i = 10; i < 36; i++) {
children.push(<Option key={i.toString(36) + i}>{i.toString(36) + i}</Option>);
}
ReactDOM.render(
<Select
mode="multiple"
style={{ width: 300 }}
placeholder="Please select"
className={styles.customSelect}
>
{children}
</Select>,
mountNode,
);
/* TestPage.less */
.customSelect {
:global {
.ant-select-selection {
max-height: 51px;
overflow: auto;
}
}
}
Two points need to be noted:
The imported antd component class name is not translated by CSS Modules, so the overridden class name .ant-select-selection must be put in :global.
Because of the previous note, the override is global. To avoid affecting other Select components, the setting needs to be wrapped by an extra classname to add range restriction
with all the above answers you cant change the styles of tags conditionally but with below approach you can.
You can do a hack and change the styles as you like of tags of select dropdown.
You can use dropdownRender of select which takes 2 arguments
menuNode
props
use props children property to reach to each tag and change the styles and you can conditionally change the styles as you like.
for reference below is the example link for code sandbox
Select Tags Styles Sanbox
May not be an efficient way to do it but you can use this for now to meet your business requirement.
Thanks
Somebody stated the selector to be
.ant-select-selection {...
However it should be selector as follows:
.ant-select-selector {
background-color: green;
}
They implemented this feature with v4 of ant design:
https://github.com/ant-design/ant-design/pull/21064
But beware before blindly upgrading from v3 -> v4 - a lot has changed:
https://github.com/ant-design/ant-design/issues/20661
menuItemSelectedIcon={(props) => {
return (mode == "multiple" ?
<Tooltip title="Check to confirm the apps alongwith the vendor">
<input type="checkbox" checked={props.isSelected}
style={{
margin: 5
}}
/>
</Tooltip>
: null)
}}
Lastly I was working on ant dropdown and it did not get style as I wanted and I did not find a good solution for that.
Then I decided to share my css solution for those who are in my situation:
.license-plate-letters {
overflow-y: hidden !important;
min-width: 240px !important;
.rc-virtual-list-holder>div {
height: auto !important;
}
.rc-virtual-list-holder-inner {
display: grid !important;
grid-template-columns: repeat(5, 1fr) !important;
flex-direction: row !important;
flex-wrap: wrap !important;
.ant-select-item-option {
padding: 0.5rem 12px !important;
&:hover {
background-color: #452380d2 !important;
color: white !important;
}
}
}
}
<Select
virtual={false}
popupClassName="license-plate-letters">
<Select.Option key={sth} Title="title">title</Select.Option>
</Select>
In angular, you can override the style with ng-deep
::ng-deep .ant-select-selector {
background-color: red;
}

Is there a way to show / hide a <div> depending on the size of the browser?

Angular JS code I am working on has media queries that can be used to limit the display of blocks with code like this:
#media screen and (max-width: 370px) {
#testGrid {
.gridHeader {
div:nth-child(2),
div:nth-child(3),
div:nth-child(n+7) {
display: none;
}
div:nth-child(6) {
border-top-right-radius: 0.4rem;
}
}
.gridBody {
div {
div:nth-child(2),
div:nth-child(3),
div:nth-child(n+7) {
display: none;
}
}
}
}
}
My comment here was that it's not good to use things like div:nth-child(2) as this would easily break if another column was added. Plus it's also difficult to maintain. I suggested to give the column names class names that matched the contents of the columns.
Still this means that I have the code that defines what shows and what does not show far removed from the HTML. Does anyone have any suggestions on a way that I could do this with AngularJS that would have the showing and hiding of columns next to the actual <div>s
You can get the current width from the $window service so you could try something like this:
DEMO
app.controller('MainCtrl', function($scope, $window) {
$scope.name = 'World';
angular.element($window).bind('resize', function(){
$scope.hideThing = ($window.innerWidth < 400);
// have to manually update $scope as angular won't know about the resize event
$scope.$digest();
});
});
Then in your HTML
<body ng-controller="MainCtrl">
<p ng-hide="hideThing" >Hello {{name}}!</p>
</body>

Resources