# How to place text box to the bottom?

**URL:** <https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469>\
**Category:** Custom Components\
**Tags:** text-input\
**Created:** [January 22, 2023, 2:06pm UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469 "2023-01-22T14:06:39Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![sahil\_bhatt](https://sea2.discourse-cdn.com/streamlit/user_avatar/discuss.streamlit.io/sahil_bhatt/32/22134_2.png) [@sahil\_bhatt](https://discuss.streamlit.io/u/sahil_bhatt)\
**Post date:** [January 22, 2023, 2:06pm UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/1 "2023-01-22T14:06:39Z")

</div>

I wanna make chat app with streamlit (without using streamlit-chat). So how can i put my text box to the bottom ? Please help !

---

<div class="post-metadata">

**Author:** ![Caroline](https://sea2.discourse-cdn.com/streamlit/user_avatar/discuss.streamlit.io/caroline/32/38736_2.png) [@Caroline](https://discuss.streamlit.io/u/Caroline)\
**Post date:** [January 26, 2023, 6:47pm UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/2 "2023-01-26T18:47:17Z")

</div>

Hey @sahil_bhatt,

Thanks for sharing your question! Please edit your post to include a code snippet so we can see how you’ve tried to implement this and make suggestions.

---

<div class="post-metadata">

**Author:** ![evsz](https://sea2.discourse-cdn.com/streamlit/user_avatar/discuss.streamlit.io/evsz/32/24334_2.png) [@evsz](https://discuss.streamlit.io/u/evsz)\
**Post date:** [March 31, 2023, 6:29pm UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/3 "2023-03-31T18:29:34Z")

</div>

Hi there Caroline! New here, hope i can jump in for a similar question.  
Im wondering if it is possible to create a ‘chat’ environment like whatsapp/telegram where the text input is at the bottom of the page and the messages appear above the textbox.

currently my solution looks like this

 ![image](https://global.discourse-cdn.com/streamlit/original/3X/7/8/7834914326800c95aac7a9c9efca06f6e9d0ac39.png)

But the ideal solution is something like this

 ![image](https://global.discourse-cdn.com/streamlit/original/3X/7/6/764e6678e52be77191774b1a433d750ec6f74a55.png)

This is my current streamlit code:

```auto
st.set_page_config(
    page_title="Assistant",
    page_icon=":robot:"
)

st.header("Welcome to Assistant")

if 'generated' not in st.session_state:
    st.session_state['generated'] = []

if 'past' not in st.session_state:
    st.session_state['past'] = []

def get_text():
    input_text = st.text_input("Input Message: ","", key="input")
    return input_text 

user_input = get_text()

if user_input:
    output = chatquery({
        "inputs": {
            "past_user_inputs": st.session_state.past,
            "generated_responses": st.session_state.generated,
            "text": user_input,
        },"parameters": {"repetition_penalty": 1.33},
    })

    st.session_state.past.append(user_input)
    st.session_state.generated.append(output)

if st.session_state['generated']:

    # for i in range(len(st.session_state['generated'])-1, -1, -1):
    # message(st.session_state["generated"][i], key=str(i))
    # message(st.session_state['past'][i], is_user=True, key=str(i) + '_user')
    for i in range(len(st.session_state['generated'])-1, -1, -1):
        message(st.session_state['past'][::-1][i], is_user=True, key=str(i) + '_user')
        message(st.session_state["generated"][::-1][i], key=str(i))

```

To sum up:

1. How can the textbox be moved to the bottom of the page?
2. How can a large collection of messages in chat format be displayed? (when the message list exceeds items on the screen they should not make the page scroll)

Thank you 🙂

---

<div class="post-metadata">

**Author:** ![Goyo](https://sea2.discourse-cdn.com/streamlit/user_avatar/discuss.streamlit.io/goyo/32/28219_2.png) [@Goyo](https://discuss.streamlit.io/u/Goyo)\
**Post date:** [March 31, 2023, 8:27pm UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/4 "2023-03-31T20:27:03Z")

</div>

> [@evsz](#):
>
> How can the textbox be moved to the bottom of the page?

Your code has undefined variables that prevent me from running it and I cannot understand everything it does just by reading. This the general idea:

1. Display the history (stored in `session_state`).
2. Ask for user input using `text_input` with a callback.
3. In the callback, modify the history as appropriate and clear the input. You can also generate the bot answers here.

```auto
def on_message_change():
    st.session_state.history.append(st.session_state.message)
    st.session_state.message = ""

if "history" not in st.session_state:
    st.session_state.history = []

for message in st.session_state.history:
    st.write(message)

st.text_input(label="Message", key="message", on_change=on_message_change)

```

> [@evsz](#):
>
> How can a large collection of messages in chat format be displayed? (when the message list exceeds items on the screen they should not make the page scroll)

Then what should they do?

---

<div class="post-metadata">

**Author:** ![evsz](https://sea2.discourse-cdn.com/streamlit/user_avatar/discuss.streamlit.io/evsz/32/24334_2.png) [@evsz](https://discuss.streamlit.io/u/evsz)\
**Post date:** [March 31, 2023, 9:10pm UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/5 "2023-03-31T21:10:58Z")

</div>

I just had a quick attempt at your solution but i couldnt figure it out. Its already late so i will take a better look at it tommorow.

here is actually my full code

```auto
import streamlit as st
from streamlit_chat import message
######################################## ________LANGCHAIN________ ####################
import os

############################################### ____LLM____ ################
# Using OPENAI LLM's
from langchain.llms import OpenAI
# Creating Prompt Templates
from langchain.prompts import PromptTemplate
# Creating Chains
from langchain.chains import LLMChain
def query(payload):
    llm = OpenAI(temperature=0.9)
    prompt = PromptTemplate(input_variables=["Product"],
                            template="{Product}")
    chain = LLMChain(llm=llm, prompt=prompt)
    response = chain.run(payload["inputs"]["text"])
    # respone is a string
    return response 
############################################### ____CHAT MODEL____ ################
from langchain.chat_models import ChatOpenAI
from langchain import LLMChain
from langchain.prompts.chat import (
    ChatPromptTemplate,
    SystemMessagePromptTemplate,
    HumanMessagePromptTemplate,
)
def chatquery(payload):
    chat = ChatOpenAI(temperature=0, streaming=True)

    template="You are a helpful assistant"
    system_message_prompt = SystemMessagePromptTemplate.from_template(template)
    human_template="{text}"
    human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
    chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])

    chain = LLMChain(llm=chat, prompt=chat_prompt)
    result = chain.run(text=payload["inputs"]["text"])
    # Result is a string
    return result

st.set_page_config(
    page_title="Assistant",
    page_icon=":robot:"
)

st.header("Welcome to Assistant")

# state to hold generated output of llm
if 'generated' not in st.session_state:
    st.session_state['generated'] = []

# state to hold past user messages
if 'past' not in st.session_state:
    st.session_state['past'] = []

# streamlit text input
def get_text():
    input_text = st.text_input("Input Message: ","", key="input")
    return input_text 

user_input = get_text()

# check if text input has been filled in
if user_input:
    # run langchain llm function returns a string as output
    output = chatquery({
        "inputs": {
            "past_user_inputs": st.session_state.past,
            "generated_responses": st.session_state.generated,
            "text": user_input,
        },"parameters": {"repetition_penalty": 1.33},
    })

    # append user_input and output to state
    st.session_state.past.append(user_input)
    st.session_state.generated.append(output)

# If responses have been generated by the model
if st.session_state['generated']:
    # Reverse iteration through the list
    for i in range(len(st.session_state['generated'])-1, -1, -1):
        # message from streamlit_chat
        message(st.session_state['past'][::-1][i], is_user=True, key=str(i) + '_user')
        message(st.session_state["generated"][::-1][i], key=str(i))

# I would expect get_text() needs to be called here as a callback
# But i have issues with retreving user_input

```

And when it comes to point 2 i mean this. the text input needs to be sticky, but the messages can be scrolling. in the image you can see the text input disapearing from the screen

 ![Screenshot from 2023-03-31 22-53-12](https://global.discourse-cdn.com/streamlit/original/3X/b/b/bb45ac56f7172ef330f7de60f94893fbdb17f077.png)

I will be back tomorrow with an update. thanks for the help. much appreciated

---

<div class="post-metadata">

**Author:** ![william](https://sea2.discourse-cdn.com/streamlit/user_avatar/discuss.streamlit.io/william/32/23536_2.png) [@william](https://discuss.streamlit.io/u/william)\
**Post date:** [March 31, 2023, 9:19pm UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/6 "2023-03-31T21:19:51Z")

</div>

use a place holder, then you can move the text box to the bottom.

 ![image](https://global.discourse-cdn.com/streamlit/original/3X/b/d/bd46d387de602ae2409411e2e27717c20ad5ee25.png)

---

<div class="post-metadata">

**Author:** ![evsz](https://sea2.discourse-cdn.com/streamlit/user_avatar/discuss.streamlit.io/evsz/32/24334_2.png) [@evsz](https://discuss.streamlit.io/u/evsz)\
**Post date:** [March 31, 2023, 10:07pm UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/7 "2023-03-31T22:07:37Z")

</div>

fixed the textbox. i used the on\_change callback in user\_input and retreived the data stored in the state through the key param in text\_input:

```auto
# check if text input has been filled in
def inputchange():
        # run langchain llm function returns a string as output
        output = chatquery({
            "inputs": {
                "past_user_inputs": st.session_state.past,
                "generated_responses": st.session_state.generated,
                "text": st.session_state.input,
            },"parameters": {"repetition_penalty": 1.33},
        })

        # append user_input and output to state
        st.session_state.past.append(st.session_state.input)
        st.session_state.generated.append(output)

# If responses have been generated by the model
if st.session_state['generated']:
    # Reverse iteration through the list
    for i in range(len(st.session_state['generated'])-1, -1, -1):
        # message from streamlit_chat
        message(st.session_state['past'][::-1][i], is_user=True, key=str(i) + '_user')
        message(st.session_state['generated'][::-1][i], key=str(i))

user_input = st.text_input("Input Message: ","", key="input", on_change=inputchange)

```

now only the problem left is the textbox disapearing after too many messages

---

<div class="post-metadata">

**Author:** ![piam](https://avatars.discourse-cdn.com/v4/letter/p/67e7ee/32.png) [@piam](https://discuss.streamlit.io/u/piam)\
**Post date:** [April 2, 2023, 5:06am UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/8 "2023-04-02T05:06:56Z")

</div>

Hi @sahil_bhatt , are you able to solve the disappearing input text box? The chat history should go up and input text should remain at its position?

---

<div class="post-metadata">

**Author:** ![Goyo](https://sea2.discourse-cdn.com/streamlit/user_avatar/discuss.streamlit.io/goyo/32/28219_2.png) [@Goyo](https://discuss.streamlit.io/u/Goyo)\
**Post date:** [April 2, 2023, 5:00pm UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/9 "2023-04-02T17:00:48Z")

</div>

I guess you could hack your way using CSS or JS or both, but I can’t help with that.

---

<div class="post-metadata">

**Author:** ![piam](https://avatars.discourse-cdn.com/v4/letter/p/67e7ee/32.png) [@piam](https://discuss.streamlit.io/u/piam)\
**Post date:** [April 3, 2023, 5:14am UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/10 "2023-04-03T05:14:01Z")

</div>

Hi @Goyo any one who could help me achieve this?

---

<div class="post-metadata">

**Author:** ![alanjo](https://sea2.discourse-cdn.com/streamlit/user_avatar/discuss.streamlit.io/alanjo/32/26583_2.png) [@alanjo](https://discuss.streamlit.io/u/alanjo)\
**Post date:** [May 15, 2023, 12:05am UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/11 "2023-05-15T00:05:41Z")

</div>

```py
styl = f"""
<style>
    .stTextInput {{
      position: fixed;
      bottom: 3rem;
    }}
</style>
"""
st.markdown(styl, unsafe_allow_html=True)

```

---

<div class="post-metadata">

**Author:** ![alonsosilvaallende](https://sea2.discourse-cdn.com/streamlit/user_avatar/discuss.streamlit.io/alonsosilvaallende/32/27922_2.png) [@alonsosilvaallende](https://discuss.streamlit.io/u/alonsosilvaallende)\
**Post date:** [June 14, 2023, 8:23pm UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/12 "2023-06-14T20:23:09Z")

</div>

Thank you very much @alanjo It works like a charm. Do you know how to make the last message to be above the text input?

---

<div class="post-metadata">

**Author:** ![John19](https://sea2.discourse-cdn.com/streamlit/user_avatar/discuss.streamlit.io/john19/32/55155_2.png) [@John19](https://discuss.streamlit.io/u/John19)\
**Post date:** [February 11, 2025, 5:09pm UTC](https://discuss.streamlit.io/t/how-to-place-text-box-to-the-bottom/36469/13 "2025-02-11T17:09:48Z")

</div>

late to the party here

I was looking to do this as well and found that the [streamlit-float](https://pypi.org/project/streamlit-float/) component does exactly this

bit more straight forward than creating placeholder yourself and writing CSS
