How can I fix the position of the input so that it is always below the element that was focused on the screen, but its size can change?

I have an element in my user interface called SkyElement that is always vertically and horizontally centered in my user interface. I also have an input called PencilInput , which I should always be below SkyElement .

In the user interface, the user has the ability to resize SkyElement (width and height), and I want PencilInput to PencilInput positioned below SkyElement , regardless of size.

PencilInput is currently displayed above SkyElement , regardless of size.

In my render function:

 <div className="left-side"> <SkyElement /> <PencilInput /> </div> 

HTML 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 greatly appreciated. Thank you

Edit: Added render() SkyElement block

Besides the code below and the .left-side .element above, that all css is for 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> ); } 
+5
source share
3 answers

One of the problems I see with your current solution is that your @mixin is not installed correctly. It creates 2 transform properties, resulting in only one thing being applied:

 transform: translate(-50%, -50%); transform: scale(1.3); 

It should be written as:

 transform: translate(-50%, -50%) scale(1.3); 

However , this is not the only problem. My recommendation would be to wrap <SkyElement/> and <PencilInput/> in a shell 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 styles for horizontal and vertical centering.

I tried using existing CSS to show how this can be done. This will need to be converted back to Sass, if you prefer. The main idea is to wrap <SkyElement/> and <PencilInput/> in the wrapping element and center them vertically. Then you can put the .pencil-input-holder element using position: absolute; . The size of <SkyElement/> will not affect the size of the <PencilInput/> element with this implementation.

Something like that:

 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> 
+5
source

I recommend wrapping them and applying flex.

  <div style={{divstyle}}> <component1/> <component2/> </div> divstyle = { display:'flex', justify-content:'center', align-items:'center', } 
+1
source

How about using display: flex ? with this centerBox div

 .centerBox { position: absolute; display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; height: 100%; } 

Full example: https://codepen.io/kkpoon/pen/rzNraz

-1
source

Source: https://habr.com/ru/post/1270162/


All Articles