Composition-vs-inheritance React
Documentation
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
https://codepen.io/gaearon/pen/ozqNOV?editors=0010
When you're viewing a pen on CodePen, the styling will most likely be applied by the code in the CSS section. It's possible that there is inline CSS in the HTML, and it's also possible JavaScript is manipulating the styling inline, but in all three instances you'll be dealing with CSS code.
The example you posted is doing all of the styling in the CSS tab. The HTML tab only contains a container for the React elements to render to.
We'll use your FancyBorder function as an example.
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
You're constructing a <div> with the class name of 'FancyBorder-' + props.color, where props.color is a variable that will be used later on.
Continuing with your example, you use the following code to create a welcome dialog:
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1>
Welcome
</h1>
</FancyBorder>
);
}
In this code, you're calling the FancyBorder function and passing through color="blue" which is referenced in the original function as props.color. It now runs 'FancyBorder-' + props.color to generate a class named: FancyBorder-blue.
Now in the CSS section, you'll see your FancyBorder-blue is already setup as a class and has styling applied to it:
.FancyBorder-blue {
border-color: blue;
}
This specific CSS applies a blue border around the box we just created. Hopefully that clears things up.
Figured it out. Those styles when opened in CodePen in edit mode are not visible when tabs are minimized. It's enough to drag them open or change the link so they are opened by default. Just a CodePen feature =)
See the difference:
https://codepen.io/gaearon/pen/ozqNOV?editors=0010
https://codepen.io/gaearon/pen/ozqNOV
.FancyBorder {
padding: 10px 10px;
border: 10px solid;
}
.FancyBorder-blue {
border-color: blue;
}
.Dialog-title {
margin: 0;
font-family: sans-serif;
}
.Dialog-message {
font-size: larger;
}
Related
I'm using LESS in one of my projects right now and I need to create some colour-schemes for different users. I'm building a portal and based on what kind of user logs in, the colour-scheme needs to change.
So in my mixins.less (which I can't modify) file I have:
#color-button-bg: #333;
#color-button-txt: #fff;
#color-button-fs: 1.5rem;
#color-button-fw: 500;
#color-button-hover-pct: 10%;
.base-btn-default(#type: button) {
background: ~"#{color-button-bg}";
border: 1px solid ~"#{color-button-bg}";
color: ~"#{color-button-txt}";
font-size: ~"#{color-button-fs}";
font-weight: ~"#{color-button-fw}";
&:hover, &:focus {
#color-btn-hover: ~"color-button-bg";
#color-btn-hover-pct: ~"color-button-hover-pct";
background: darken(##color-btn-hover,##color-btn-hover-pct);
border-color: darken(##color-btn-hover,##color-btn-hover-pct);
color: ~"#{color-button-txt}";
}
}
And in a separate file with client-specific mixins I tried the following:
/* Override default color with theme-color */
.theme-styling() {
#color-button-bg: #main-theme-color;
}
Then finally I wanted to add a class to my <body> tag and style the colour-scheme based on that classname:
body.theme-a {
#main-theme-color: teal;
.theme-styling();
}
However, this doesn't seem to work. I think it has something to do with scoping / Lazy evaluation, but I'm not that experienced in LESS yet, to see where my error is.
I created a Codepen for it, without the separate files and in a bit of a simplified form:
https://codepen.io/jewwy0211/pen/JVNZPv
I've just played around with your codepen a bit. When you define the variable in your mixin, it does work, the problem is that you then don't use that variable in the mixin or in the class that contains the mixin.
So, if you've got 2 buttons like this:
<div class="wrapper one">
<button>Theme 1</button>
</div>
<div class="wrapper two">
<button>Theme 2</button>
</div>
You can call their theme-specific variable mixins in their respective classes to get the vars set, but you then must use the vars within the same class:
.wrapper.one {
.theme-styling-1();
background-color: #color-button-bg;
}
.wrapper.two {
.theme-styling-2();
background-color: #color-button-bg;
}
/* Theme Vars */
.theme-styling-1() {
#color-button-bg: teal;
}
.theme-styling-2() {
#color-button-bg: red;
}
EDIT: Here's a codepen: https://codepen.io/mmshr/pen/OGZEPy
I'm trying to style a component in my React application, but I do not want to create an external stylesheet because it's a small project. How can I style this image component without using an external stylesheet?
return (
<div>
<Image>
<div>
<img src='./resources/image.png alt='image'>
</div>
</Image>
</div>
);
I've found resources online for using inline styling on a specific element, but I want to make my code clean by putting it at the top of the component like using a style tag at the top of an HTML file. I haven't been able to find anything that resembles this in React.
For inline styles you can define a style object, either at the top of the file, or in your render method, and then refer to it:
var myStyle = { margin: 10 }
return (
<div>
<Image>
<div>
<img style={myStyle} src='./resources/image.png alt='image'>
</div>
</Image>
</div>
)
More info in the docs: https://reactjs.org/docs/dom-elements.html#style
Internal CSS styling in JSX is very similar to how it's done in HTML. The only difference is that you need to declare the style names as variables because they are treated like JS objects. With this in mind, you also need to end each property with a comma instead of a semicolon, and the last property should have no punctuation at the end. Using this approach, you should also use style={} instead of className={}. You can read more about JSX styling here.
const myStyle = {
width: '300px',
height: '300px',
border: '2px solid black'
}
const Image = () => {
return (
<div>
<img style={myStyle} src='./resources/image.png alt='image'>
</div>
);
}
You can do something like this:
const Image = styled.div`
background: #1d9ac2;
img {
border: 1px solid red;
}
`;
There are several solutions for this, and a big debate about which one is "the best".
I don't know which one is the best, but I can tell you which one I use:
Styled components (https://www.styled-components.com/)
With this, you would define an object like this
let styled = require('styled-components');
// Or for fancy people
import styled from 'styled-components';
const Image = styled.div`
background-color: red;
/* You can even put classes or selectors in here that will match the sub-components */
.some_class_used_inside { color: black; }
img { width: 100px }
`
and use it like this
return (
<div>
<Image> {/* This will be the `<div>` with `background-color: red` */}
<div className="some_class_used_inside"> {/* This will now have `color: black` applied */
<img src='./resources/image.png alt='image'> {/* This will have `width: 100px` applied to it */}
</div>
</Image>
</div>
);
Ofcourse, there are many other libraries to do it, and everyone will have to find their own favorite I guess :)
I'm currently working on a dating website for a school project, but i'm stuck and not sure if i'm on the right way.
On the user profile, i want a list of the photos the user choose to show, and i want a hover on the photo where the pointer is.
In my state i added a listPhotoHover: [ ], a tab that contains variables true or false. listPhotoHover[0] = true means the first photo of the list has a hover, false means no hover.
I map and add a div for every photo with a onMouseEnter( ) that takes the photo index and set it an hover if fired.
The hover appears if listPhotoHover[index] exists, the hover div has an onMouseLeave( ) that takes the photo index and set the hover of the photo as false.
Everything seems to work but i'm not sure if it's the best way to do it, and when i move very fast on every photo the hover is still there i think the onMouseLeave( ) don't run.
Here's my code
Map of every photo :
photos.map((photo, index) => {
return
<div className={`flex row`} key={index} >
<img
className={classes.userPhotos}
src={photo}
alt={`photo de ${name}`}
onMouseEnter={() => { this.haveHover(index) }}
/>
{
listPhotoHover[index]
? <div
className={`
absolute flex center alignCenter
${classes.userPhotos} ${classes.photoHover}
`}
onMouseLeave={
() => { this.removeHover(index) }
}
/>
: null
}
</div>
})
function when onMouseEnter() or onMouseLeave() is fired:
haveHover (index, value) {
const tab = this.state.listPhotoHover
tab[index] = value
this.setState({listPhotoHover: tab})
}
I would like to know why does the onMouseLeave() don't work when my pointer move very fast and also what is the best way to do an hover on a map.
Thank you for your advices and sorry if i don't write english correctly
ps: i checked previous questions and didn't find any answer yet :(
Josephine
I don't believe you need javascript to achieve your desired effect. If it is simply to show something when the image is hovered, you can uses some advanced CSS selectors to do this. Run the snippet below to
html {
font-family: sans-serif;
font-size: 10px;
}
.wrap {
position: relative;
}
.image {
width: 80px;
height: 80px;
}
.imageinfo {
display: none;
width: 80px;
height: 17px;
background: #cc0000;
color: #efefef;
padding: 3px;
text-align: center;
box-sizing: border-box;
position: absolute;
bottom: -13px;
}
/* here's the magic */
.image:hover+.imageinfo {
display: block;
}
Hover the image to see the effect
<div class="wrap">
<img class="image" src="https://www.fillmurray.com/80/80" />
<div class="imageinfo">
Bill Murray FTW
</div>
</div>
I just realized i did it all wrong, i added a className with a '&:hover' on the div containing one photo, and it works. No need javascript :D
I don't know why i wanted to complicate it haha..
className:
ANSWER: {
'&:hover': {
opacity: '0.4',
cursor: 'pointer'
}
}
div with the photo:
photos.map((photo, index) => {
return <div className={`flex row ${classes.ANSWER}`} key={index} >
<img
className={classes.userPhotos}
src={photo}
alt={`${name}`}
/>
</div>
})
Hope my mistake will help some people
I am working on a one-pager WordPress site, and I need to hide the logo of the page (#logo) on the first section (#home). The whole page is a one-pager, so the first section does not need the logo, in fact it should only appear for the other sections below the first one.
Can this be accomplished using CSS?
If it is, then I also want to change the color of the menu elements for the first section, and be something else for the others.
Short answer: No.
You will need to write some JavaScript or jQuery to determine when the first section (i.e. home section) is no longer in the view window.
The logo is typically within the <header>. It's one element within the HTML markup. It does not have a relationship to the sections. With styling, you position it where you want and then scroll the document to view the rest of the content sections.
I assume with this being a one-pager, you want the <header> to be fixed. It's a good assumption since you want to display the logo in the same spot for each section, except the first one.
How
There are many ways to accomplish this behavior. Essentially, you need to determine if the home section is in the browser window or not. When it is, the logo is hidden; else, it's displayed.
One strategy is:
Set the position where the logo will show by grabbing the 2nd section's position in the document (i.e. its offset().top position).
Then determine where the 1st section is within the window. If it's > showPosition, then it's out of view.
Here's some code to get you started. You'll need to adapt it for your specific needs.
(function ( $, window, document ) {
"use strict";
var sectionContainers,
showPosition = 400;
var init = function () {
initSection();
logoHandler();
}
function initSection() {
sectionContainers = $( '.section-container' );
showPosition = $( sectionContainers[1] ).offset().top;
}
function logoHandler() {
var $logo = $( '#logo' );
if ( $( sectionContainers[0] ).offset().top >= showPosition ) {
$logo.show();
}
$( window ).scroll( function () {
if ( $( this ).scrollTop() > showPosition ) {
$logo.show();
} else {
$logo.hide();
}
} );
}
$( document ).ready( function () {
init();
} );
}( jQuery, window, document ));
body {
color: #fff;
}
.site-header {
position: fixed;
}
.site-logo {
font-weight: bold;
border: 5px solid #fff;
padding: 10px;
}
.section-container {
width: 100%;
height: 400px;
text-align: center;
padding: 50px 5%;
background-color: #627f00;
}
.section-container:nth-child(odd) {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header class="site-header" itemscope itemtype="http://schema.org/WPHeader">
<p id="logo" class="site-logo" itemprop="headline" style="display: none;">Logo</p>
</header>
<section id="home" class="section-container">
this is the home section
</section>
<section id="about" class="section-container">
this is the about section
</section>
<section id="about" class="section-container">
this is the portfolio section
</section>
JSFiddle
I'm new to css and I can't figure out how to position one component inside another in React. I can show them separately, but when I put one inside another. I don't see the one inside. I think the problem is in the css file
#homePage{
section{
h1{
text-align: left; //this is shown
}
//here I want to add the other React component but I don't know how
}
}
And the render method:
<div id="homePage">
<Component1>
<section>
<h1>Hi</h1>
<Component2>
</Component2>
</section>
</Component1>
</div>
Thanks.
From what i understand , you could have the className attribute defined inside your Component2's HTML tags.
class Component2 extends Component{
render(){
return(
<section className="component2styles">
This is Component2
</section >
);
} }
Now , you can change ur style sheet as
#homePage{
section{
h1{
text-align: left; //this is shown
}
//components2 style will be nested here
section.component2styles{
border:1px solid blue;
}
}
}
Or as an alternative you can try inline-styles , seems to be gaining a lot of traction in React development.
render(){
var styleobj={color:'red'};
return( <section style={styleobj} > This is Component 2 </section> )
}
Did you add some class/id to your Component2 like <Component2 className="my-specific-class" /> to style it?
(btw, I hope your css is less/sass one to allow nested styles like you did)
EDIT
By adding className attr. to your Component2, I mean adding it in Component2 render method like
render: function() {
return (
<div id="your-id" className="your-class">
some html here
</div>
);
}