I have an element in my UI called a SkyElement
, which is always vertically and horizontally centered in my UI. I also have an input, called a PencilInput
that's I want to always be below the SkyElement
.
In the UI, the user has the ability to change the size (width and height) of the SkyElement
and I want the PencilInput
to be positioned below the SkyElement
, regardless of size.
Right now, the PencilInput
is displaying above the SkyElement
, regardless of size.
In my render
function:
<div className="left-side">
<SkyElement />
<PencilInput />
</div>
The HTML of PencilInput
:
<div className='pencil-input-holder'>
<div className='pencil-svg' />
<input className='pencil-input' onChange={this.handleChange} value={this.state.title} />
</div>
In my css:
@mixin absolute-center {
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.left-side {
background: linear-gradient(180deg, #000000 0%, #205F8A 45.56%, #8852BB 100%);
position: relative;
.element {
@include absolute-center;
transform: scale(1.3);
transform-origin: center center;
}
}
.pencil-input-holder {
border-bottom: 4px dashed rgba(255, 255, 255, 0.3);
width: 50%;
margin: 0 auto;
.pencil-svg {
background: url('../images/pencil.svg') center center no-repeat;
width: 27px;
height: 39px;
display: inline-block;
position: relative;
top: 60px;
left: 20px;
}
}
input.pencil-input {
position: relative;
font-family: 'GT America Compressed Regular';
text-align: center;
font-size: 59px;
color: rgba(255, 255, 255, 0.5);
background: transparent;
left: 50%;
transform: translateX(-50%);
border: none;
&:focus { outline: none; }
}
Any help would be appreciated. Thanks!
Edit: Added render()
block of SkyElement
Aside from the code below and the .left-side .element
code above, that's the entirety of the css for the SkyElement
render() {
const { connectDragSource, isDragging, hideSourceOnDrag, transformElement, top, left } = this.props;
// hide on drag in slot view
if (isDragging && hideSourceOnDrag) {
return null;
}
const halfSize = this.props.size / 2;
const transform = transformElement ? `translate(-50%, -50%)` : '';
const style = {
width: `${this.props.size}px`,
height: `${this.props.size}px`,
borderRadius: '50%',
background: this.radialGradient(),
opacity: isDragging ? 0.2 : this.props.opacity,
boxShadow: this.boxShadow(),
transform,
transition: 'background 0.2s',
position: 'relative',
top,
left,
};
return connectDragSource(
<div onClick={this.editElement} className='element' style={style}>
{
this.props.labelPosition
? <ElementLabel title={this.props.title} position={this.props.labelPosition } />
: null
}
</div>
);
}
One issue I see with your current solution, your @mixin
is setup incorrectly. It produces 2 transform
properties, which results in only one being applied:
transform: translate(-50%, -50%);
transform: scale(1.3);
This should be written as:
transform: translate(-50%, -50%) scale(1.3);
However, that is not the only issue. My recommendation would be to wrap the <SkyElement/>
and <PencilInput/>
in a wrapper component/element to center the group of elements horizontally/vertically.
<div className="left-side">
<CenterElements>
<SkyElement />
<PencilInput />
</CenterElements>
</div>
or
<div className="left-side">
<div class="center">
<SkyElement />
<PencilInput />
</div>
</div>
This element/component will contain the styles to horizontally and vertically center it.
I've attempted to use the existing CSS to show how this could be done. This will need to be converted back into Sass if you prefer that. The basic idea is to wrap the <SkyElement/>
and <PencilInput/>
in a wrapper element and center that vertically. You can then position the .pencil-input-holder
element using position: absolute;
within that. The <SkyElement/>
's size will not effect the size of the <PencilInput/>
element with this implementation.
Something along these lines:
html,
body {
height: 100%;
min-height: 100%;
}
.left-side {
background: linear-gradient(180deg, #000000 0%, #205F8A 45.56%, #8852BB 100%);
position: relative;
height: 100%;
width: 100%;
}
.element-container {
position: relative;
width: 100%;
top: 50%;
transform: translateY(-50%);
text-align: center;
}
.left-side .element {
display: inline-block;
height: 80px;
width: 80px;
line-height: 80px;
text-align: center;
border-radius: 50%;
background-color: rgba(255,255,255, 0.5);
}
.pencil-input-holder {
border-bottom: 4px dashed rgba(255, 255, 255, 0.3);
width: 50%;
position: absolute;
margin: 0 auto;
left: 50%;
transform: translateX(-50%);
}
.pencil-input-holder .pencil-svg {
background: url("../images/pencil.svg") center center no-repeat;
width: 27px;
height: 39px;
display: inline-block;
position: relative;
top: 60px;
left: 20px;
}
input.pencil-input {
position: relative;
font-family: 'GT America Compressed Regular';
text-align: center;
font-size: 59px;
color: rgba(255, 255, 255, 0.5);
background: transparent;
left: 50%;
transform: translateX(-50%);
border: none;
}
input.pencil-input:focus {
outline: none;
}
<div class="left-side">
<div class="element-container">
<div class="element" style="position: relative;">
Sky
</div>
<div class="pencil-input-holder">
<div class="pencil-svg">
Pencil
</div>
<input class="pencil-input" onChange={this.handleChange} value={this.state.title} />
</div>
</div>
</div>
I recommend wrapping them and applying flex.
<div style={{divstyle}}>
<component1/>
<component2/>
</div>
divstyle = {
display:'flex',
justify-content:'center',
align-items:'center',
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With