Can't get elements to stack - css

CSS isn't necessarily my strong suit but I have no idea why I can't get these two elements to stack? I set the parent position to relative and the child to absolute I also give the child a higher z-index but just can't get it to work. The <Icon /> is always offset to the right.
Code
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
const propTypes = {
iconName: PropTypes.string,
color: PropTypes.string,
};
const defaultProps = {
iconName: 'add_box',
color: '#27B678',
};
const MaterialIcon = props => (
<i className={`material-icons ${props.className}`}>
{props.iconName.replace(/['"]+/g, '')}
</i>
);
const Icon = styled(MaterialIcon)`
color: ${props => props.color.replace(/['"]+/g, '')};
font-size: 36px;
position: absolute;
z-index: 10;
top: 10%;
left: 0;
right: 0;
bottom: 0;
`;
const Divider = props => (
<div
className="mx2"
style={{ position: 'relative', border: '1px solid #ececec' }}
>
<Icon
iconName={props.iconName}
color={props.color}
/>
</div>
);
Divider.propTypes = propTypes;
Divider.defaultProps = defaultProps;
export default Divider;

You need to use top and left to position the icon over the divider. You should give left a negative value equal to half the width of the icon so that it is centered over the divider. For instance, if the icon width is 50px, your Icon style should look like this:
const Icon = styled(MaterialIcon)`
color: ${props => props.color.replace(/['"]+/g, '')};
font-size: 36px;
position: absolute;
z-index: 1;
top: 10%;
left: -25px;
`;
Make sure to also give your divider a z-index of 0 so that the Icon appears on top of it.

Related

Vertical Fixed Box at bottom of screen using MUI

So far I have tried this:
import "./styles.css";
import { Box, Typography } from "#mui/material";
import styled from "#emotion/styled";
export default function App() {
const MainStyle = styled("div")(({ theme }) => ({
position: "fixed",
zIndex: 99999,
right: 0,
bottom: 0
}));
return (
<MainStyle>
<Box sx={{ transform: "rotate(-90deg)", backgroundColor: "blue" }}>
<Typography sx={{ color: "white" }}>CHAT WITH US!</Typography>
</Box>
</MainStyle>
);
}
The problem with this is that half the box is out of the screen and is not all the way to the right.
My goal is to have it all the way in the right corner but also show the entire box like up against the side like https://proxy-seller.com/ have their "chat with us, we are online" just I want it on the right side.
writing-mode: vertical-rl; you can the mentioned css property.
Simple html example for writing-mode: vertical-rl, you can lear more about it from this.
.main {
position: relative;
}
.text {
writing-mode: vertical-rl;
border: 2px solid #000;
position: absolute;
top: 15px;
right: 15px;
height: 120px;
}
<main class="main">
<h1 class="text">Test text</h1>
</main>

Styled Component not rendering when placed outside of component function

My styled component does not render when I place it outside of the 'Bubble' function. It renders when the styled components are declared within the 'Bubble' function but I then get an warning saying I shouldn't do that.
There are no errors that indicate what the problem is.
`
import styled from 'styled-components';
const Container = styled.div`
width: 0;
height: 0;
`;
const Inner = styled.div`
position: relative;
border-radius: 50%;
width: ${props => props.size};
height: ${props => props.size};
left: ${props => props.left};
top: ${props => props.left};
background: linear-gradient(180deg, #1A2132 0%, rgba(26, 33, 50, 0.1) 100%);
transform: rotate(${props => props.rotate}deg);
`;
export default function Bubble (props) {
return (
<Container>
<Inner
width={props.size}
height={props.size}
left={props.left}
top={props.top}
rotate={props.rotate}
/>
</Container>
)
}
`
Thank you!!

CSS Ripple effect with pseudo-element causing reflow

I'm trying to create the material ripple effect with styled-components (which is unable to import the material web-components mixins). I want to stick with using the after element for the foreground effect, to keep the accesibility tree intact.
However, most notably on mobile, the ripple transition is causing reflow in the button's content. It would seem to happen because of the display change (from none to block), but I have tried some alternatives which don't share this artifact, and this side-effect is still present.
Here's my code (I'm using some props to set the ripple, but you can hard-set them if you want to reproduce): [Here was an outdated version of the code]
Thanks for the attention.
Edit: The bug only happens when I add a hover effect to the button, very weird. Below follows the link and a code sample (you will have to set a react repository in order to reproduce it, unfortunately)
https://github.com/Eduardogbg/ripple-hover-reflow-bug
import React, { useRef, useReducer } from 'react';
import ReactDOM from 'react-dom';
import styled from 'styled-components'
const ButtonBase = styled.button`
cursor: pointer;
width: 250px;
height: 6vh;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
outline: none;
position: relative;
overflow: hidden;
border-width: 0;
background-color: cyan;
:hover {
filter: brightness(1.06);
}
::after {
content: '';
pointer-events: none;
width: ${({ ripple }) => ripple.size}px;
height: ${({ ripple }) => ripple.size}px;
display: none;
position: absolute;
left: ${({ ripple }) => ripple.x}px;
top: ${({ ripple }) => ripple.y}px;
border-radius: 50%;
background-color: ${({ ripple }) => ripple.color};
opacity: 0;
animation: ripple ${({ ripple }) => ripple.duration}ms;
}
:focus:not(:active)::after {
display: block;
}
#keyframes ripple {
from {
opacity: 0.75;
transform: scale(0);
}
to {
opacity: 0;
transform: scale(2);
}
}
`
const rippleReducer = ref => (ripple, event) => {
const { x, y, width, height } = ref.current.getBoundingClientRect()
const size = Math.max(width, height)
return {
...ripple,
size,
x: event.pageX - x - size / 2,
y: event.pageY - y - size / 2
}
}
const DEFAULT_RIPPLE = {
size: 0,
x: 0,
y: 0,
color: 'white',
duration: 850
}
const Button = props => {
const ref = useRef(null)
const [ripple, dispatch] = useReducer(
rippleReducer(ref),
{ ...DEFAULT_RIPPLE, ...props.ripple }
)
return (
<ButtonBase
ref={ref}
className={props.className}
ripple={ripple}
onClick={event => {
event.persist()
dispatch(event)
}}
>
{props.children}
</ButtonBase>
)
}
ReactDOM.render(
<div style={{
backgroundColor: 'red',
width: '500px', height: '500px',
display: 'grid',
placeItems: 'center'
}}>
<Button>
<span style={{ fontSize: '30px' }}>
abacabadabaca
</span>
</Button>
</div>,
document.getElementById('root')
);
The problem seems to be related to this chromium bug that was supposedly solved a few years ago: Image moves on hover when changing filter in chrome
Setting transform: translate3d(0,0,0); looks like a fix, though my eye isn't pixel-perfect.

React component stops working when I add css to it

I have a component that has a state "style" which changes to a random color in my colors array whenever a button is clicked. The state is passed inside a style attribute so that the backgroundColor would become whatever the state is. This is working but whenever I try to add css to the button, it stops working as intended. I have a hunch that it could be due to the position absolute that I used but I have no idea why it's doing that.
All I could do was comment out the CSS to make the button work again but that really doesn't solve my issue.
import React, {Component} from 'react';
import "./Tap.css";
class Tap extends Component{
constructor(props){
super();
this.state={
style: ''
}
this.handleClick = this.handleClick.bind(this);
}
handleClick(){
const colors = ["#68ad45", "#123456", "#987546", "#ab23c6", "#324517", "#456819"];
let i = Math.floor(Math.random() * 6);
this.setState({
style: colors[i]
});
}
render(){
return(
<div className="Tap" style={{backgroundColor: this.state.style}}>
<button onClick={this.handleClick}>Click Here</button>
</div>
);
}
}
export default Tap;
// ========================== CSS file ==========================
.Tap button{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: none;
outline: none;
padding: 10px;
font-size: 200px;
cursor: pointer;
}
No error messages, just no result coming from the button after it's been styled with the css.
This is because: position: absolute which is added to button,
So Tab div have no height now
One solution: is to div that div fixed height:
.Tap {
height: 50px;
}
See Example 1
But if you noticed that the tab not aligned with button because of absolute position.
Other Solution position the Tab not the button as absolute with some padding:
See example 2
Just do this simple change <button onClick={this.handleClick} style={{backgroundColor: this.state.style}}>Click Here</button>
check sample code - https://stackblitz.com/edit/react-soy8a4

Can't get buttons to wrap to new line instead of overflowing container

I couldn't get a JSFiddle to work properly with React and some other dependencies, so I hope the link to this Github repo is sufficient for demonstrating the issue:
https://github.com/ishraqiyun77/button-issues/
Basically, a group of buttons is rendered and they should be auto-widened to fill white space and take up the whole row. This works in Chrome, Edge, Safari, and Firefox. It looks like this:
This isn't happening in IE. I've been messing with it for hours and haven't made much progress:
Here is the code, although could clone the repo I posted above:
// component.jsx
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import {
Button,
Col,
Modal,
ModalBody,
ModalHeader,
Row
} from 'reactstrap';
import styles from '../assets/scss/app.scss';
class TestPrint extends Component {
constructor(props) {
super(props);
this.state = {
modal: false,
}
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState({
modal: !this.state.modal
})
}
renderContent() {
let buttons = [];
for (let i = 1; i < 50; i++) {
buttons.push(
<Col key={i}>
<Button
key={i}
className='cuts-btn'
>
{i} - Test
</Button>
</Col>
);
};
return buttons;
}
render() {
return (
<div>
<Button
style={
{
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
}
}
onClick={this.toggle}
>
Open Modal for Buttons
</Button>
<Modal
size='lg'
isOpen={this.state.modal}
toggle={this.toggle}
className='results-modal'
>
<ModalHeader toggle={this.toggle}>
Button Issues
</ModalHeader>
<ModalBody>
<div className='results-bq-cuts'>
<Row>
{this.renderContent()}
</Row>
</div>
</ModalBody>
</Modal>
</div>
)
}
}
ReactDOM.render(<TestPrint />, document.getElementById('app'));
.results-modal {
max-width: 1200px;
.modal-content {
.modal-body {
margin-left: 13px;
margin-right: 13px;
.results-bq-cuts {
width: 100%;
.col {
padding:2px;
}
.cuts-btn {
font-size: 11px;
padding: 3px;
width: 100%;
box-shadow: none;
}
// .col {
// padding: 2px;
// display: table-cell;
// flex-basis: 100%;
// flex: 1;
// }
// .cuts-btn {
// font-size: 11px;
// padding: 3px;
// width: 100%;
// box-shadow: none;
// }
}
}
}
}
I have all of the <Button> wrapped in <Col> because that should be what is filling the white space by increasing the size of the button.
Thanks for the help!
IE11 doesn't like working out the width of flex items. If you add flex-basis: calc( 100% / 24 ); to .col it works :) Obviously use any width you want, but what I've given replicates the 21 boxes on one line. But essentially flex-basis needs a defined width to work.
​
Or add an extra class to each element (such as col-1 ) This'll also achieve the same thing.

Resources